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

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

ccwgpt 2024-10-13 01:38 25 浏览 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)设置场景,利用配置<groups>-><run>-><include>/<exclude>让Group1和Group3执行,Group2不执行(实际上如果<groups>中直接不写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+<parameter name="xx" value="xxx"/>

这个时候就需要在方法上加上注解@Parameters,并在xml配置文件中利用<parameter name="xx" value="xxx"/>的方式传参

注:也可用<methods><methods/>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: 同一个<test>中的用例运行在同一个线程下,不同<test>中的用例可以运行在不同线程下
    • classes:同一个<class>中的用例运行在同一个线程下,不同<class>中的用例可以运行在不同线程下


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

    2)三种不同级别选择

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

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

    测试结果:

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

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

    测试结果:

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

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

    测试结果:

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

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

    相关推荐

    RACI矩阵:项目管理中的角色与责任分配利器

    作者:赵小燕RACI矩阵RACI矩阵是项目管理中的一种重要工具,旨在明确团队在各个任务中的角色和职责。通过将每个角色划分为负责人、最终责任人、咨询人和知情人四种类型,RACI矩阵确保每个人都清楚自己...

    在弱矩阵组织中,如何做好项目管理工作?「慕哲制图」

    慕哲出品必属精品系列在弱矩阵组织中,如何做好项目管理工作?【慕哲制图】-------------------------------慕哲制图系列0:一图掌握项目、项目集、项目组合、P2、商业分析和NP...

    Scrum模式:每日站会(Daily Scrum)

    定义每日站会(DailyScrum)是一个Scrum团队在进行Sprint期间的日常会议。这个会议的主要目的是为了应对Sprint计划中的不断变化,确保团队能够有效应对挑战并达成Sprint目标。为...

    大家都在谈论的敏捷开发&amp;Scrum,到底是什么?

    敏捷开发作为一种开发模式,近年来深受研发团队欢迎,与瀑布式开发相比,敏捷开发更轻量,灵活性更高,在当下多变环境下,越来越多团队选择敏捷开发。什么是敏捷?敏捷是一种在不确定和变化的环境中,通过创造和响应...

    敏捷与Scrum是什么?(scrum敏捷开发是什么)

    敏捷是一种思维模式和哲学,它描述了敏捷宣言中的一系列原则。另一方面,Scrum是一个框架,规定了实现这种思维方式的角色,事件,工件和规则/指南。换句话说,敏捷是思维方式,Scrum是规定实施敏捷哲学的...

    敏捷项目管理与敏捷:Scrum流程图一览

    敏捷开发中的Scrum流程通常可以用一个简单的流程图来表示,以便更清晰地展示Scrum框架的各个阶段和活动。以下是一个常见的Scrum流程图示例:这个流程图涵盖了Scrum框架的主要阶段和活动,其中包...

    一张图掌握项目生命周期模型及Scrum框架

    Mockito 的最佳实践(mock方法)

    记得以前面试的时候,面试官问我,平常开发过程中自己会不会测试?我回答当然会呀,自己写的代码怎么不测呢。现在想想我好像误会他的意思了,他应该是想问我关于单元测试,集成测试以及背后相关的知识,然而当时说到...

    EffectiveJava-5-枚举和注解(java枚举的作用与好处)

    用enum代替int常量1.int枚举:引入枚举前,一般是声明一组具名的int常量,每个常量代表一个类型成员,这种方法叫做int枚举模式。int枚举模式是类型不安全的,例如下面两组常量:性别和动物种...

    Maven 干货 全篇共:28232 字。预计阅读时间:110 分钟。建议收藏!

    Maven简介Maven这个词可以翻译为“知识的积累”,也可以翻译为“专家”或“内行”。Maven是一个跨平台的项目管理工具。主要服务于基于Java平台的项目构建、依赖管理和项目信息管理。仔...

    Java单元测试框架PowerMock学习(java单元测试是什么意思)

    前言高德的技术大佬在谈论方法论时说到:“复杂的问题要简单化,简单的问题要深入化。”这句话让我感触颇深,这何尝不是一套编写代码的方法——把一个复杂逻辑拆分为许多简单逻辑,然后把每一个简单逻辑进行深入实现...

    Spring框架基础知识-第六节内容(Spring高级话题)

    Spring高级话题SpringAware基本概念Spring的依赖注入的最大亮点是你所有的Bean对Spring容器的存在是没有意识的。但是在实际的项目中,你的Bean必须要意识到Spring容器...

    Java单元测试浅析(JUnit+Mockito)

    作者:京东物流秦彪1.什么是单元测试(1)单元测试环节:测试过程按照阶段划分分为:单元测试、集成测试、系统测试、验收测试等。相关含义如下:1)单元测试:针对计算机程序模块进行输出正确性检验工作...

    揭秘Java代码背后的质检双侠:JUnit与Mockito!

    你有没有发现,现在我们用的手机App、逛的网站,甚至各种智能设备,功能越来越复杂,但用起来却越来越顺畅,很少遇到那种崩溃、卡顿的闹心事儿?这背后可不是程序员一拍脑袋写完代码就完事儿了!他们需要一套严谨...

    单元测试框架哪家强?Junit来帮忙!

    大家好,在前面的文章中,给大家介绍了以注解和XML的方式分别实现IOC和依赖注入。并且我们定义了一个测试类,通过测试类来获取到了容器中的Bean,具体的测试类定义如下:@Testpublicvoid...

    取消回复欢迎 发表评论: