使用testMe自动生成单元测试用例

文章目录

1、testMe简介

公司对于系统单元测试覆盖率有要求,需要达到50%或80%以上才可以,但是对于之前的老项目或者是前期赶进度未添加单元测试用例的项目来说,手动添加单元测试耗时又费力,这时候我们就需要一款能够提高效率的一款插件来帮助我们提高单元测试覆盖率,经过对比temstMe、Squaretest、Diffblue三个插件,最终选择了一款免费的testMe来作为我们自动化单元测试用例生成插件。

2、插件对比

2.1 testMe

优点:

  1. 开源免费
  2. 使用方便,上手容易
  3. 生成的代码比较简洁

缺点:

  1. 默认方法上都会有throws exception,但是可以通过定制模板去掉
  2. mock方法入参构建不好,经常用null作为入参,需要自己调整入参
  3. 不能增量的生成新方法的单测用例

2.2 Squaretest

优点:

  1. 使用方便,上手容易
  2. 生成的测试方法入参会根据逻辑需要的字段自动填充属性
  3. 可以增量生成指定方法的单元测试用例

缺点:

  1. 收费,但是可以试用30天
  2. 部分生成的方法没有Assert断言判断结果,也需要微调代码
  3. 存在部分重复代码,例如构建的入参实体,如果入参一致的情况下会存在重复代码

2.3 Diffblue

优点:

  1. 功能强大,生成的单元测试用例几乎不用改动就能正常运行
  2. 收费版本会得到其公司支持

缺点:

  1. 功能全的版本需要收费
  2. 免费版本只能用于开源项目,公司项目感觉慎用
  3. 会将代码上传到远端进行生成测试用例

3、IDEA插件安装

File------>Settings------>Plugins------>marketplace,搜索testMe,然后install就好了,插件安装完成后需要重启一下。

4、单测用例

4.1 maven依赖

复制代码
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>3.5.0</version>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>4.5.1</version>
    <scope>test</scope>
</dependency>

4.2 生成用例

我们找到需要生成单元测试的类,然后右键点击Generate。

在弹窗中选择testMe。

继续选择Junit4 & Mockito来生成单元测试用例。

我们看下生成的单元测试用例。

这个单元测试用例有几点柑橘不是很好,第一点是生成的类没有类注释头,第二是Mock 注解 和InjectMocks注解挨在一起,希望能空一行,第三是生成的脚注有点多余,我们不需要。所以这时候我们需要通过自定义模板来修改这些。

5、自定义模板

File------>Settings------>TestMe------>TestMe template 找到testMe的模板。

我们找到Junit4 & Mockito这个模板,点击上面菜单拷贝一份模板。

我们在此拷贝的模板基础上进行修改。

首先我们添加一下类注释。

复制代码
/**
 * @author author
 * @date ${DATE} ${TIME}
 */

其次我们在测试类上添加RunWith注解。

复制代码
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;

第三我们添加Mock和InjectMocks添加空行及删除脚注。

以下为本人使用的完整模板代码。

复制代码
#parse("TestMe macros.java")
#set($hasMocks=$MockitoMockBuilder.hasMockable($TESTED_CLASS.fields))
#if($PACKAGE_NAME)
package ${PACKAGE_NAME};
#end

import org.junit.Assert;
import org.junit.Test;
#if($hasMocks)
import org.junit.Before;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
//import static org.mockito.Mockito.*;
#end

/**
 * @author author
 * @date ${DATE} ${TIME}
 */
 
#parse("File Header.java")
@RunWith(MockitoJUnitRunner.class)
public class ${CLASS_NAME} {
#renderMockedFields($TESTED_CLASS.fields)

#renderTestSubjectInit($TESTED_CLASS,$TestSubjectUtils.hasTestableInstanceMethod($TESTED_CLASS.methods),$hasMocks)
#if($hasMocks)

    @Before
    public void setUp() {
        MockitoAnnotations.${MockitoMockBuilder.initMocksMethod}(this);
    }
#end
#foreach($method in $TESTED_CLASS.methods)
#if($TestSubjectUtils.shouldBeTested($method))

    @Test
    public void #renderTestMethodName($method.name)() {
#if($MockitoMockBuilder.shouldStub($method,$TESTED_CLASS.fields))
#renderMockStubs($method,$TESTED_CLASS.fields)

#end
        #renderMethodCall($method,$TESTED_CLASS.name)
#if($method.hasReturn())        Assert.#renderJUnitAssert($method)#end
    }
#end
#end
}

6、使用自定义模板生成用例

我们在使用同样的流程来根据自定义模板生成单元测试用例。

我们看下生成的新的测试用例格式如下。

代码格式会比之前好一点,但是生成的单元测试用例还是需要我们微调一下才能跑。

7、调试用例

如果只是注重单元测试覆盖率,那么按照上面的方法生成即可,如果还需要单元测试用例跑通,那么基本上需要我们在微调一下代码。

相关推荐
圆山猫21 分钟前
[Virtualization](四):Linux KVM/RISC-V 的 vCPU 运行路径
java·linux·risc-v
城管不管1 小时前
ReAct、Plan-and-Execute、Reflection 三大智能 Agent 范式核心区别
java·人工智能·算法·spring·ai·动态规划
IT小白杨1 小时前
从环境制备到自动化工作流:多账号运营的工程化架构拆解
java·经验分享·自动化·安全架构·指纹浏览器
豆瓣鸡2 小时前
算法日记 - Day3
java·开发语言·算法
萧瑟余晖2 小时前
Java深入解析篇九之NIO详解
java·网络·nio
The Chosen One9852 小时前
高进度算法模板速记(待完善)
java·前端·算法
极光代码工作室4 小时前
基于SpringBoot的课程预约系统
java·springboot·web开发·后端开发
Leighteen5 小时前
`try-finally` 里的 `return`:为什么 `finally` 会悄悄改掉返回值、吞掉异常
java·开发语言
名字还没想好☜6 小时前
Go 的 time.After 在 select 循环里内存泄漏:定时器堆积原理与 timer.Reset 正确姿势
java·数据库·golang·go·goroutine
圆山猫6 小时前
[Virtualization](三):RISC-V H-extension 与 Guest 执行模式
android·java·risc-v