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配置

<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>6.9.10</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>2.2.2.RELEASE</version>
    <scope>test</scope>
</dependency>

简单示例:

@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配置线程数等等。

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java TestNG是一种用于编写和执行单元测试的框架。它可以帮助开发人员进行自动化测试,并提供了丰富的功能和灵活的配置选项。 在Java TestNG中,可以使用@Test注解来标记测试方法。通过使用不同的注解参数,可以控制测试方法的执行顺序、分组和依赖关系。 引用\[1\]中的示例展示了一个使用@Test注解的测试类TestCase1。其中,@Test(enabled=false)表示该测试方法不会被执行,而@Test表示该测试方法会被执行。通过这种方式,可以选择性地执行测试方法。 引用\[2\]中的示例展示了如何使用priority参数来控制测试方法的执行顺序。priority的数值越小,优先级越高,测试方法会按照优先级从小到大的顺序执行。 引用\[3\]中的示例展示了如何使用dependsOnMethods参数来定义测试方法之间的依赖关系。在这个示例中,TestNgLearn2方法依赖于TestNgLearn1方法,只有在TestNgLearn1方法执行成功后,TestNgLearn2方法才会被执行。 总结来说,Java TestNG可以通过注解参数来控制测试方法的执行顺序、分组和依赖关系,从而实现灵活的单元测试。 #### 引用[.reference_title] - *1* *3* [TestNG单元测试框架详解](https://blog.csdn.net/lovedingd/article/details/106784561)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Java笔记-单元测试框架TestNG](https://blog.csdn.net/qq_19645167/article/details/126280996)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值