百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

利器 | TestNG 与 Junit 对比,测试框架如何选择?

lipiwang 2025-03-14 18:37 26 浏览 0 评论


TestNG 和 Junit 作为两大流行的测试框架,有哪些区别?各有哪些优缺点?该如何选择呢?这里简要总结下:

1. Junit 更适合隔离性比较强的单元测试;

2. TestNG 是比 Junit 涵盖功能更全面的测试框架,具有参数化和分组的特性,可以做数据驱动;

3. TestNG 被设计应用覆盖所有的测试,单元、功能、端到端、集成测试等;

4. TestNG 依赖测试时对于依赖方法失败后的用例标记为跳过,而不是像 Junit 标记为失败,减少失败原因排查成本;

5. TestNG 可以针对失败用例回归测试,增加测试针对性和效率,而 Junit 需要将所有测试用例重新执行;

6. TestNG 更适合测试工程师需要的大范围的复杂的集成测试;

注:以上对比指的是 TestNG 和 Junit4 版本的对比,最新的 Junit5 框架已经完善了功能特性,也涵盖了 TestNG 所包含的功能,如果选择 Junit 框架,建议直接选用 Junit5,Junit5 还在推广普及中;
具体可参考《Junit5简介、构成、新特性及基本使用-常用注解、套件执行》

---Junit与TestNG的注解区别---

项目测试实操演练

下面通过项目实操讲解二者区别。做项目测试之前,需要先添加 maven 依赖,如下图所示:

1.基本测试


Junit和TestNG对于测试方法的标注都是@Test,另外在方法执行前后加上@BeforeMethod、@AfterMethod


测试结果:

由测试结果可看到在每个测试用例执行前都会先执行@BeforeMethod注解的方法,之后都会执行@AfterMethod注解的方法

2.@BeforeClass和@AfterClass

在测试类运行之前运行@BeforeClass和@AfterClass


测试结果:


由测试结果可以看出在测试类执行前后会先后执行一次被@BeforeClass和@AfterClass注解的方法

3.套件测试
TestNG的套件管理有点“特别”,它是以一个xml文件作为统一配置文件的,一般会命名为testNG.xml,实际上文件的命名随意,you happy just ok!

  • 执行时通过运行xml文件
  • 最基本的套件管理规则:suite->test->classes->class
  • 同一个test下的测试类看做是一个整体,其中的注解对整个test整体都是生效的

下面看实操演示,当前有3个测试类SuiteTest1、SuiteTest2和SuiteTestConfig

在resource下创建套件配置文件testNGSuite.xml


3.1 套件测试之
@BeforeSuite和@AfterSuite

1)在SuiteTest1、SuiteTest2测试类中分别输入测试用例:

2)再在SuiteTestConfig测试类中输入@BeforeSuite和@AfterSuite注解方法和@Test方法

3)最后在配置文件testNGSuite.xml中配置套件执行顺序将SuiteTest1、SuiteTestConfig"包"成一个test整体,SuiteTest2、SuiteTestConfig"包"成一个test整体;然后依顺序执行
注:suite和test Tag需要给一个name,否则会报错

测试结果:


从测试结果我们可以看到@BeforeSuite和@AfterSuite仅仅在suite执行前后分别执行一次


3.2 套件测试之
@BeforeTest+@AfterTest

在测试类SuiteTestConfig中输入@BeforeTest+@AfterTest注解的方法,xml套件配置不变

测试结果:

由测试结果可以看到,在每个test执行前后都会先后执行一次由@BeforeTest、@AfterTest注解的方法

4.忽略测试@Test(enable=false)

在测试方法test1的注解中设置属性enable=false

测试结果:

由测试结果可以看到test1被忽略了,并没有执行

5.分组测试

5.1方法分组之
@Test(groups=“xxx”)、@BeforeGroups+@AfterGroups

分别将方法test1和test2分为“测试1组”和“测试2组”

再在测试1组执行前执行@BeforeGroups注解方法,在测试2组执行后执行@AfterGroups注解方法

测试结果:

5.2测试类分组 @Test(groups=“xxx”)

当前有3个测试类 ClassGroups1Test、ClassGroups2Test、ClassGroups3Test


1)分别将这3个测试类进行分组Group1、Group2、Group3


2)将这3个测试类以3、2、1的执行顺序引入xml套件配置文件


3)设置场景,利用配置->->/让Group1和Group3执行,Group2不执行(实际上如果中直接不写Group2,它也不会执行)

xml套件配置文件呈现结果:

测试结果:


由测试结果可以看到,测试类分组在Group3和Group1的方法依次执行了,而Group2分组中的测试类未被执行


注:如果测试用例的逻辑顺序设计的较合理,平常使用分组的频率可能没那么高

6.异常测试

测试时,我们可能期望的结果就是抛出某种异常,比如单元测试时输入非法入参,程序期望抛出异常,而这是期望的正确结果,我们希望用例是测试通过的,这时就需要用到异常测试注解:@Test(exceptedExceptions = XXXException.class)

测试结果:

注: 单元测试平常更多的可能由研发人员自己完成,一般功能和接口测试我们测试工程师期待的都是后端对异常处理后返回的一个状态码code和message信息


7.依赖测试

有时候一个用例的执行要依赖其他用例的执行结果,例如购买商品前需要依赖用户登录成功才可以,这个时候就需要使用@Test(dependsOnMethods = {"funtion name"})对另一个用例进行依赖

7.1 依赖用例成功

然后我们直接运行pay方法,结果如下:


由测试结果我们可以看到虽然我们直接执行了pay方法,但是由于pay方法是依赖于login方法的,所以会先执行login方法


7.2 依赖用例失败

我们让被依赖的login用例执行失败,直接运行pay方法,观察结果:


测试结果:


由测试结果可以看到几点现象:

被依赖的用例执行失败,后面的用例会直接跳过忽略

测试结果显示为忽略而不是失败,这样当有成百上千条用例因为被依赖的用例失败而执行不通过时,可以只排查被依赖用例失败原因即可;否则如Junit4全部标记为失败的话会造成排查问题和回归测试效率的极大浪费

8.参数化测试


有的方法需要传参,好比登录成功时我们需要用户的姓名和ID号

参数的传递直接写在代码中不利于维护更改,也不方便不懂代码的测试人员进行参数修改,这个时候就需要参数化测试


8.1 参数化测试1:
@Parameters+

这个时候就需要在方法上加上注解@Parameters,并在xml配置文件中利用的方式传参

注:也可用tag对指定的方法进行参数传递


xml里完成传参:


测试结果:

8.2 参数化测试2:
@Test(dataProvider = “name”)+@DataProvider

1)利用@Test(dataProvider = "name")+@DataProvider(name="name")将多组数据传递到一个方法中依次执行

测试结果:


2)利用@Test(dataProvider = "name")+@DataProvider(name="name")指定测试方法,传递指定入参进行测试


分别单独运行方法userInfo1和userInfo2得到测试结果:
userInfo1:

userInfo2:

9.多线程测试

9.1多线程测试注解实现
@Test(invocationCount=10,threadPoolSize=4)

参数说明:
官方给出的解释是如下

简单来说就是:

invocationCount表示方法要运行几次,threadPoolSize表示线程池大小,且要配合invocationCount才起作用。现在将userInfo1方法用多线程执行10次,线程池大小设为4,打印当前线程id以观察验证

测试结果:

从测试结果中可以看到4个不同的线程一共将方法userInfo1执行了10次

9.2 多线程测试xml实现:
parallel(methods|tests|classes)+thread-count

参数解释:
官方文档的解释如下:


parallel(methods|tests|classes):设置使用多线程,且有methods|tests|classes三种不同级别选择


  • methods: 所有用例都可以在不同的线程下执行,包括依赖的用例
    • tests: 同一个中的用例运行在同一个线程下,不同中的用例可以运行在不同线程下
    • classes:同一个中的用例运行在同一个线程下,不同中的用例可以运行在不同线程下


    1)创建3个方法,打印线程ID

    2)三种不同级别选择

    methods-所有用例都可以在不同的线程下执行

    设置parallel为methods级别,thread-count为3,进行测试

    测试结果:

    2.2)tests-同一个中的用例运行在同一个线程下,不同中的用例可以运行在不同线程下
    再创建测试类ThreadTest,添加三个方法并打印thread ID

    设置parallel为tests级别,thread-count为3,进行测试

    测试结果:

    2.3)classes-同一个中的用例运行在同一个线程下,不同中的用例可以运行在不同线程下

    设置parallel为classes级别,thread-count为3,进行测试

    测试结果:

    注: 虽然框架本身说明了是多线程安全的,但是由于我们自身编码可能不能保证严格规范,容易造成多线程不安全,所以建议不要适用多线程测试,而是适用多进程测试

    (文章来源于霍格沃兹测试学院)

    相关推荐

    软件测试|MySQL CROSS JOIN:交叉连接的详细解析

    简介在MySQL数据库中,CROSSJOIN是一种用于生成两个或多个表的笛卡尔积的连接方法。CROSSJOIN不需要任何连接条件,它将左表的每一行与右表的每一行进行组合,从而生成一个包含所...

    「MySQL笔记」left join-on-and 与 left join-on-where 的区别

    1.摘要关于这两种写法的重要知识点摘要如下:left-join时,即使有相同的查询条件,二者的查询结果集也不同,原因是优先级导致的,on的优先级比where高on-and是进行韦恩运算连接...

    MySQL中的JOIN——联合查询的基本语法

    MySQL中的JOIN指令用来将两个或多个表中的数据进行联合查询,根据连接条件来匹配记录,从而得到需要的结果集。在MySQL中,常见的JOIN类型包括INNERJOIN、LEFTJOIN和RIGH...

    MySQL 中的 CROSS JOIN:强大的连接工具

    CROSSJOIN在MySQL里是一种挺特别的连接操作,它能弄出连接表的笛卡尔积。这就是说,要是表A有m行,表B有n行,那ACROSSJOINB的结果就会有m*n...

    大厂必问:MySQL 三表 JOIN 操作的解析与性能优化,效率又如何?

    大厂必问:MySQL三表JOIN操作的解析与性能优化策略,效率又如何?点击关注,开启技术之旅!大家好,这里是互联网技术学堂,无论你是一名程序员、设计师、还是对技术充满好奇心的普通人,都欢迎你加入...

    面试题:MySQL 的 JOIN 查询优化(mysql查询优化方法)

    MySQL的JOIN查询优化是提升数据库性能的关键环节。以下是综合多个技术文档的核心优化策略,按优先级和实现难度分类:一、索引优化:性能提升的基础为连接字段建立索引确保参与JOIN的列(通常...

    Flink中处理维表关联技术实现路径

    在Flink中处理维表关联大体氛围TableSQLLookupJoin和DataStream算子函数,主要技术实现路径:I.FlinkSQL/TableAPI中的Lookup...

    深入剖析Zookeeper原理(一)整体设计

    1.ZK集群架构设计与特性1.ZK集群架构设计:ZK主要分为三种角色:Leader(领导者):一个Zookeeper集群同一时间只会有一个实际工作的Leader,它会发起并维护与各Follwer及...

    多种负载均衡算法及其Java代码实现

    首先给大家介绍下什么是负载均衡负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。负载均衡,英...

    一分钟了解SpringCloud中的ribbon到底是什么,原理是啥?

    1.概念ribbon是一款客户端负载均衡器,用于微服务之间的负载均衡。首先,什么是客户端负载均衡?如图,ribbon可以通过注册中心获取服务列表,然后自己执行自己的负载均衡策略来决定要访问哪个微服务,...

    Step by Step之腾讯云短信-验证码实践

    在商城小程序和前端上线用了一阵子之后,用户提出了体验提升的需求,如忘记密码、绑定用户、快捷注册等,作为业界最佳实践的短信验证码登录、重置密码和注册等功能开发也就提上日程了,本文就以重置密码为例,将验证...

    10分钟入门响应式:Springboot整合kafka实现reactive

    Springboot引入Reactor已经有一段时间了,笔者潜伏在各种技术群里暗中观察发现,好像scala圈子的同仁们,似乎对响应式更热衷一点。也许是因为他们对fp理解的更深吧,所以领悟起来障碍性更少...

    使用java随机生成有个性的用户名,LOL地名+水浒传,合计2808个

    *随机生成用户名*取水浒传108好汉名字*取LOL地名26个,组合而成*一共可以生成2808个不同特色的用户名如果你在上网的时候,用户名难取的话,这里有很多可选择的用户名,现提供100个...

    深入理解Math.random()的概率分布特性

    直接上源码/***Returnsa{@codedouble}valuewithapositivesign,*返回一个带符号的double类型的数字,说人话就是返回一个非负...

    编程英文 - 创建/生成/构建 (create/generate/build)

    在软件开发中,create、generate和build这三个词经常被用到,它们都与"创造"或"产生"某些东西有关,但在具体使用场景和含义上有所不同。基本含义creat...

    取消回复欢迎 发表评论: