今天,我们将介绍一个工具Squaretest,它是一个用于自动生成单元测试的插件。它也将被使用,因为该公司最近实施了代码质量控制指标,以评估各种项目的单元测试覆盖率和声纳扫描的各种问题。

许多旧项目和旧代码,或者需要匆忙交付的项目,都严重缺少单元测试,覆盖率不到5%。所以最近几天,几个小伙伴一直在疯狂地堆积单元测试。三个人把两天的单元测试累积到30%。所以我也来帮忙写了两篇。当我写第二篇时,我发现这项工作不应该由人来做。我们应该查看原始代码,然后根据逻辑编写各种模拟,我觉得有一些东西可以遵循,所以我检查了一下,发现有插件可以帮助我们做到这一点。然后我看了一眼。
我使用这个想法。首先,让我们下载插件。文件-->设置-->插件,搜索Squaretest,然后安装它。安装插件后,需要重新启动它

 

重新启动后,菜单栏会有一个额外的方形测试。让我们来讨论一下如何使用它。通过查看菜单的最后一项:生成测试方法(帮助),您也可以看到它的演示,但演示尚未完成。我将在下面截图,向您展示如何使用它和一些经验。

 

首先,我们开一个类,这是我们要测试的类。这个类有七个公共方法,因为Squaretest生成的单元测试方法只能生成public。当然,这是合理的!毕竟,私人电话必须由公众拨打。

 

如果我们要手工编写这个类的单元测试,那么需要一段时间来研究它。现在让我们来看看我的操作。打开类,将光标放在代码中,然后右键单击鼠标以选择Generate…

然后您将看到两个熟悉的图标。第一次选择第二个选项时,它将允许您为单元测试选择模板。因为我已经选择了它,所以我不会再次弹出演示,但稍后我会告诉您如何更改模板。

选择第二项后,将弹出一个框。在这里,它将自动识别需要Mock的当前类的成员变量。直接单击“确定”

 

将使用类的真实目录层次结构在测试文件夹中自动创建单元测试类。类名是原始类名,后跟Test

 

我会把代码发给你,看看它生成了什么。让我们看看它是否可怕、可怕、可怕。七种单元测试方法将在几秒钟内发布。你要写多长时间?毕竟,时间就是金钱!那我们试试吧!
public class CrawlerScreenShotServiceImplTest {     @Mock
    private CrawerScreenShotTaskMapper mockCrawerScreenShotTaskMapper;
    @Mock
    private CrawerScreenShotTaskLogMapper mockCrawerScreenShotTaskLogMapper;
    @InjectMocks
    private CrawlerScreenShotServiceImpl crawlerScreenShotServiceImplUnderTest;
    @Before     public void setUp() {         initMocks(this);     }     @Test
    public void testReceiveData() {         // Setup
        final CrawlerScreenShotVO vo = new CrawlerScreenShotVO();
        vo.setUrl("url");         vo.setPcFlag(false);
        vo.setMembergroup("membergroup");         vo.setTaskType(0);
        vo.setUrlType(0);
        when(mockCrawerScreenShotTaskLogMapper.saveSelective(any(CrawerScreenShotTaskLog.class))).thenReturn(0);
        when(mockCrawerScreenShotTaskMapper.saveBatch(Arrays.asList(new CrawlerScreenShotTask(0L, "url", "imageOssUrl", false, false, "memberGroup", 0, 0, "fileName", new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime(), new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime(), false, "skuCode", "state", "operater")))).thenReturn(0);
        // Run the test
        final Result<String> result = crawlerScreenShotServiceImplUnderTest.receiveData(vo);
        // Verify the results     }     @Test
    public void testListJobScreenShotTask() {         // Setup
        // Configure CrawerScreenShotTaskMapper.listJobScreenShotTask(...).
        final CrawlerScreenShotTaskDto crawlerScreenShotTaskDto = new CrawlerScreenShotTaskDto();
        crawlerScreenShotTaskDto.setId(0L);
        crawlerScreenShotTaskDto.setUrl("url");
        crawlerScreenShotTaskDto.setSkuCode("skuCode");
        crawlerScreenShotTaskDto.setPcFlag(false);
        crawlerScreenShotTaskDto.setMemberGroup("memberGroup");
        crawlerScreenShotTaskDto.setUrlType(0);
        crawlerScreenShotTaskDto.setFileName("fileName");
        crawlerScreenShotTaskDto.setTaskType(0);
        crawlerScreenShotTaskDto.setState("state");
        final List<CrawlerScreenShotTaskDto> crawlerScreenShotTaskDtos = Arrays.asList(crawlerScreenShotTaskDto);
        when(mockCrawerScreenShotTaskMapper.listJobScreenShotTask(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime())).thenReturn(crawlerScreenShotTaskDtos);
        // Run the test
        final List<CrawlerScreenShotTaskDto> result = crawlerScreenShotServiceImplUnderTest.listJobScreenShotTask();
        // Verify the results     }     @Test     public void testQuery() {
        // Setup
        final NikeScreenShotListRequestVo requestVo = new NikeScreenShotListRequestVo();
        requestVo.setUrl("url");         requestVo.setUrlType(0);
        requestVo.setStartTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
        requestVo.setEndTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
        requestVo.setStatus(0);         requestVo.setPcFlag(0);
        requestVo.setPageNum(0);         requestVo.setPageSize(0);
        // Configure CrawerScreenShotTaskMapper.query(...).
        final PimScreenShotVo pimScreenShotVo = new PimScreenShotVo();
        pimScreenShotVo.setId(0L);         pimScreenShotVo.setUrl("url");
        pimScreenShotVo.setImageOssUrl("imageOssUrl");
        pimScreenShotVo.setStatus(0);         pimScreenShotVo.setPcFlag(false);
        pimScreenShotVo.setCreateTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
        pimScreenShotVo.setUrlType(0);         pimScreenShotVo.setMsg("msg");
        final List<PimScreenShotVo> pimScreenShotVos = Arrays.asList(pimScreenShotVo);
        when(mockCrawerScreenShotTaskMapper.query(any(NikeScreenShotListRequestVo.class))).thenReturn(pimScreenShotVos);
        // Run the test
        final PageInfo<PimScreenShotVo> result = crawlerScreenShotServiceImplUnderTest.query(requestVo);
        // Verify the results     }     @Test
    public void testQuerySelectBoxData() {         // Setup
        // Configure CrawerScreenShotTaskMapper.query(...).
        final PimScreenShotVo pimScreenShotVo = new PimScreenShotVo();
        pimScreenShotVo.setId(0L);         pimScreenShotVo.setUrl("url");
        pimScreenShotVo.setImageOssUrl("imageOssUrl");
        pimScreenShotVo.setStatus(0);         pimScreenShotVo.setPcFlag(false);
        pimScreenShotVo.setCreateTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
        pimScreenShotVo.setUrlType(0);         pimScreenShotVo.setMsg("msg");
        final List<PimScreenShotVo> pimScreenShotVos = Arrays.asList(pimScreenShotVo);
        when(mockCrawerScreenShotTaskMapper.query(any(NikeScreenShotListRequestVo.class))).thenReturn(pimScreenShotVos);
        // Run the test
        final PimScreenShotTaskParamsDto result = crawlerScreenShotServiceImplUnderTest.querySelectBoxData();
        // Verify the results     }     @Test
    public void testFindExecutionScreenShotTaskCount() {         // Setup
        when(mockCrawerScreenShotTaskMapper.findExecutionScreenShotTaskCount()).thenReturn(0);
        // Run the test
        final Integer result = crawlerScreenShotServiceImplUnderTest.findExecutionScreenShotTaskCount();
        // Verify the results         assertEquals(0, result);     }     @Test
    public void testFindCrawerScreenshotTaskByCreateTime() {         // Setup
        final CrawlerScreenShotTaskSyncDto crawlerScreenShotTaskSyncDto = new CrawlerScreenShotTaskSyncDto();
        crawlerScreenShotTaskSyncDto.setId(0L);
        crawlerScreenShotTaskSyncDto.setUrl("url");
        crawlerScreenShotTaskSyncDto.setSkuCode("skuCode");
        crawlerScreenShotTaskSyncDto.setTaskType(0);
        crawlerScreenShotTaskSyncDto.setStatus(0);
        crawlerScreenShotTaskSyncDto.setLastModifyTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
        crawlerScreenShotTaskSyncDto.setOperater("operater");
        crawlerScreenShotTaskSyncDto.setMsg("msg");
        final List<CrawlerScreenShotTaskSyncDto> expectedResult = Arrays.asList(crawlerScreenShotTaskSyncDto);
        // Configure CrawerScreenShotTaskMapper.findCrawerScreenshotTaskByCreateTime(...).
        final CrawlerScreenShotTaskSyncDto crawlerScreenShotTaskSyncDto1 = new CrawlerScreenShotTaskSyncDto();
        crawlerScreenShotTaskSyncDto1.setId(0L);
        crawlerScreenShotTaskSyncDto1.setUrl("url");
        crawlerScreenShotTaskSyncDto1.setSkuCode("skuCode");
        crawlerScreenShotTaskSyncDto1.setTaskType(0);
        crawlerScreenShotTaskSyncDto1.setStatus(0);
        crawlerScreenShotTaskSyncDto1.setLastModifyTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
        crawlerScreenShotTaskSyncDto1.setOperater("operater");
        crawlerScreenShotTaskSyncDto1.setMsg("msg");
        final List<CrawlerScreenShotTaskSyncDto> crawlerScreenShotTaskSyncDtos = Arrays.asList(crawlerScreenShotTaskSyncDto1);
        when(mockCrawerScreenShotTaskMapper.findCrawerScreenshotTaskByCreateTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime())).thenReturn(crawlerScreenShotTaskSyncDtos);
        // Run the test
        final List<CrawlerScreenShotTaskSyncDto> result = crawlerScreenShotServiceImplUnderTest.findCrawerScreenshotTaskByCreateTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
        // Verify the results         assertEquals(expectedResult, result);
    }     @Test     public void testQueryCrawlerDashboard() {         // Setup
        when(mockCrawerScreenShotTaskMapper.queryCrawlerDashboard(0, 0, 0, new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime(), new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime())).thenReturn(0);
        // Run the test
        final Integer result = crawlerScreenShotServiceImplUnderTest.queryCrawlerDashboard(0, 0, 0, new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime(), new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
        // Verify the results         assertEquals(0, result);     } }
不要惊慌。这个断言是为了检查单元测试的结果是否符合预期。

 

怎样这并不令人兴奋,也不酷。每秒超过90行的代码覆盖率超过90%。

如上所述,第一次进来时,您将被要求选择单元测试模板。如果要切换,可以在单元测试类中按快捷键Alt+M,或者在Squaretest菜单中按倒数第一个。按下快捷键的效果如下。我选择了这个模板,您也可以使用它作为参考。

好了,上面的SQUARETEST部分结束了。当然,拉动并不为时过早。这个类是一个比较成功的案例,您仍然需要做一些小的修改。毕竟,它生成的测试数据可能与if-else数据不匹配,对吗?但这很容易改变。这从if
else的自我分析变为调试,查看生成的数据是否有问题。更改数据将被传递。无论如何,我对它很满意,我可以适当地节省70%的工作量。

解决了上述问题后,发现了另一个问题。对于VO、DTO、entity、Command和Model等实体类,我们通常使用lombok注释,如get、set和约束构造函数。但是,该工具只能为这些实体类的构造函数生成单元测试,而不能为get
set方法生成单元测试。因此,我们编写一个由实体类继承的基方法,只需编写两行磁带。请参见以下代码:
@SpringBootTest @RunWith(MockitoJUnitRunner.class)
public abstract class BaseVoEntityTest<T> {     protected abstract T getT();
    private void testGetAndSet() throws IllegalAccessException, InstantiationException, IntrospectionException,
            InvocationTargetException {         T t = getT();
        Class modelClass = t.getClass();
        Object obj = modelClass.newInstance();
        Field[] fields = modelClass.getDeclaredFields();
        for (Field f : fields) {
            boolean isStatic = Modifier.isStatic(f.getModifiers());
            // 过滤字段
            if (f.getName().equals("isSerialVersionUID") || f.getName().equals("serialVersionUID") || isStatic || f.getGenericType().toString().equals("boolean")
                    || f.isSynthetic()) {                 continue;
            }
            PropertyDescriptor pd = new PropertyDescriptor(f.getName(), modelClass);
            Method get = pd.getReadMethod();
            Method set = pd.getWriteMethod();
            set.invoke(obj, get.invoke(obj));         }     }     @Test
    public void getAndSetTest() throws InvocationTargetException, IntrospectionException,
            InstantiationException, IllegalAccessException {
        this.testGetAndSet();     } }
同样,我们通过Squaretest在实体类上生成单元测试,然后继承我上面写的基类。vo的单元测试代码略有更改,如下所示

 

观看运行后,覆盖率为100%,这是合适的。通过这两种解决方案,我们可以在一天内实现60%以上的覆盖率。不要太激动。你可以尝试一下。当然,这不是一个专门为跑腿而编写的单元测试。我们还可以使用这个工具在后续开发中生成和测试我们自己的代码,这也提高了我们的工作效率!

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信