TestNG单元测试实战

TestNG单元测试实战

单元测试是什么

对软件中最小可测试单元进行验证。小到一个方法,大到一个类、一个模块。都可以用单元测试覆盖。

单元测试有必要写吗

现状:

  1. 面对日复一日排满的需求,没有时间去写。

  2. 再者业务逻辑变化快,对应的单元测试代码也得调整。不愿写。

  3. 用postman,接口api也能满足http测试。

写单测好处:

  1. 避免低级的bug发到开发环境或测试环境。
    • 在线测试分支覆盖不全的情况。

  2. 提高代码正确性。
    • 判断方法的返回值和预期值是否一致。

  3. 能简单理清代码逻辑。
    • 阅读单元测试代码能简单快速的了解逻辑。方便后面的同事了解此方法功能。以及怎么使用。

如果不写单测,那我们可能会用postman或swagger-ui来测试某个controller接口。
但很多时候我们需要对service中多个分支,对某个工具类验证代码正确性,这时候还不涉及接口的调用,以及接口不能覆盖全异常分支的情况。此时这种场景就可以用单测来完成。

Junit 和 TestNG对比

Junit和TestNG都是Java测试框架。

看Testng官网介绍: TestNG - Welcome

对比Junit,TestNG优势如下:

  • 注解更全

  • 支持依赖测试

  • 支持测试组

  • 支持多线程测试

TestNG + Spring boot test实战

引入maven配置


    org.testng
    testng
    6.9.10
    test


    org.springframework.boot
    spring-boot-starter-test
    2.2.2.RELEASE
    test

简单示例:

@SpringBootTest
public class DemoTest extends AbstractTestNGSpringContextTests {

    @Autowired
    private IDemoService service;

    @Autowired
    private DemoController demoController;

    @Autowired
    private PreprocessConfig preprocessConfig;

    @Autowired
    private AuthInterceptor interceptor;

    public MockMvc mockMvc;

    //测试方法前运行
    @BeforeMethod
    public void setup(){
        //通过注册一个或多个controller实例和配置springmvc编程方式来构建一个mockmvc实例。
        mockMvc = MockMvcBuilders.standaloneSetup(demoController).
                //添加拦截器
                addInterceptors(interceptor).
                //请求数据预处理
                setControllerAdvice(preprocessConfig).
                build();
    }

    @Test
    public void testDemoList() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/demo/list")
                .header("token", "xxxxxx")
                .contentType(MediaType.TEXT_HTML_VALUE)
                .queryParam("ascs", "createDate"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.content().string(Matchers.notNullValue()));
    }

    @Test
    public void testProcessMerge() {
        int num = service.processMerge(1);
        Assert.assertEquals(num, 1);
    }
}

此单元测试类中包含了service和controller测试。其中setup()用于构建MockMvc实例。

MockMvc: 服务器端Spring MVC测试支持的主要入口点。可调用其perform方法来构建请求。

SpringBootTest注解: 此注解表明基于spring boot启动的测试类。

AbstractTestNGSpringContextTests抽象类: 集成了spring测试上下文框架。 此抽象类也实现了ApplicationContextAware接口,spring容器初始化时,会注入spring应用上下文。

日期预处理

如前端传的string需转成实体属性中LocalDateTime格式,则需要对请求参数预处理,可定义一个日期预处理类:

@ControllerAdvice
public class PreprocessConfig{
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(LocalDateTime.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                if (StringUtils.isNotBlank(text)){
                    this.setValue(LocalDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                } else {
                    this.setValue(null);
                }
            }
        });
   }
}

ControllerAdvice和InitBinder注解实现全局数据预处理。

事务支持

AbstractTransactionalTestNGSpringContextTests抽象类继承自AbstractTestNGSpringContextTests抽象类,用于加载spring配置,支持事务。

在测试方法上加入@Rollback用于事物回滚处理。

TestNG常用注解

  • @BeforeSuite:在该套件中所有测试用例执行前运行。

  • @AfterSuite:在该套件中所有测试用例执行后运行。

  • @BeforeGroups:调用属于该组的第一个方法前运行。

  • @AfterGroups:调用属于该组最后一个方法后运行。

  • @BeforeClass:在调用当前类第一次测试方法前运行。

  • @AfterClass:当前类所有测试方法结束后运行。

  • @BeforeMethod:在每个测试方法开始运行前执行。

  • @AfterMethod:在每个测试方法运行结束后执行。

  • @Test:表明为测试方法。

执行顺序:@BeforeSuite -> @BeforeClass -> @BeforeGroups -> @BeforeMethod -> @Test -> @AfterMethod -> @AfterGroups -> @AfterClass -> @AfterSuite。

其中Test注解中有如下方法:

@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({METHOD, TYPE, CONSTRUCTOR})
public @interface Test {
    public String[] groups() default {};
    public String[] dependsOnGroups() default {};
    public String[] dependsOnMethods() default {};
    public int threadPoolSize() default 0;
    public String dataProvider() default "";
}

可以用dependsOnGroups表明依赖的组,dependsOnMethods设置方法依赖,threadPoolSize配置线程数等等。

你可能感兴趣的:(java,单元测试)