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

news2024/11/17 1:29:19

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,进行测试

测试结果:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/139284.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

世界第一虚拟乐队举办了一场 AR 音乐会 #Gorillaz

“世界第一虚拟乐队” 是谁&#xff1f;23 年前&#xff0c;一支名为 Gorillaz 的乐队在英国埃塞克斯横空出世。和当时主流乐队形式不同的是&#xff0c;这支乐队以虚拟形象出现&#xff0c;凭借着过硬的音乐制作实力和别具一格的虚拟乐队形象&#xff0c;不久后就席卷了全球&a…

如何打造敏捷项目管理团队?【金曼说4】

曾经乔布斯说过他此生最骄傲的事不是创造了苹果&#xff0c;而且团队。由此也说明团队的重要性。一支优秀的团队能打造出无数优秀的产品和项目。无论是在商场还是战场上&#xff0c;快速反应和适应能力都至关重要&#xff0c;在技术和干扰性力量导致变革速度加快的时代更是如此…

HTML 常见面试题

一、HTML5&#xff08;超文本标记语言&#xff0c;第五次重大修改&#xff09;二、HTML5新特性①&#xff1a;新的语义标签 header footer nav aside article section②&#xff1a;新的表单控件 calendar date time email url search③&#xff1a;音频、视频&#xff08; aud…

地产2022价值启示录:房企必须闯过的“三重门”

回顾2022年&#xff0c;中国最大的经济变向之一&#xff0c;无疑就是地产增量时代的落幕。过去一整年&#xff0c;地产行业在“冷热交替”中前行。上半年&#xff0c;疫情、交付延期、停贷潮等阴霾萦绕在众多房企头顶上&#xff0c;市场需求疲软之下业绩下滑&#xff0c;难以看…

《MySQL系列-InnoDB引擎10》InnoDB关键特性-异步IO

InnoDB 关键特性 InnoDB存储引擎的关键特性包括&#xff1a; Insert Buffer (插入缓冲)Double Write (两次写)Adaptive Hash Index (自适应哈希索引)Async IO (异步IO)Flush Neighbor Page (刷新领接页) 这些特性为InnoDB存储引擎带来了更好的性能以及更高的可靠性。 异步IO 为…

在外打工好久不回老家,用python为家里贴上新年春联

每逢春节&#xff0c;无论城市还是农村&#xff0c; 家家户户都要挑漂亮的红春联贴于门上&#xff0c;辞旧迎新&#xff0c;增加喜庆的节日气氛。 唠叨神话 据说这一习俗起于宋代&#xff0c;在明代开始盛行&#xff0c; 到了清代&#xff0c;春联的思想性和艺术性都有了很…

SpringBoot @ConfigurationProperties使用详解

SpringBoot ConfigurationProperties使用详解 目录SpringBoot ConfigurationProperties使用详解1.1 简述1.2 场景一1.3 场景二1.4 场景三1.5 聊聊EnableConfigurationProperties1.1 简述 在Spring Boot中注解ConfigurationProperties有三种使用场景&#xff0c;而通常情况下我…

51单片机学习笔记_6 IO通信:电脑与单片机之间的通信

通信 单片机还可以通过IO口实现多种通信。 串行通信&#xff1a;一条数据线&#xff0c;一次发1bit&#xff0c;发很久。 并行通信&#xff1a;多条数据线&#xff0c;同时发送&#xff0c;发的速度快多了但是费用高、接收困难、抗干扰性差。 异步通信&#xff1a;发送和接…

PMP、ACP、软考证书,当前哪些值得一考?

看自己的偏向吧&#xff0c;要说考的话&#xff0c;是都值得考的。ACP和PMP都是美国PMI发起的考试&#xff0c;软考是国内的考试。PMP是项目管理证书&#xff0c;学习的内容是项目管理&#xff0c;包含大约一半的敏捷项目管理的内容&#xff0c;ACP的内容都是敏捷项目管理&…

操作系统第三次实验-动态分区存储管理(python代码实现)

一、实验目的&#xff1a; 目的&#xff1a;熟悉并掌握动态分区分配的各种算法&#xff0c;熟悉并掌握动态分区中分区回收的各种情况&#xff0c;并能够实现分区合并。 任务&#xff1a;用高级语言模拟实现动态分区存储管理。 二、实验内容&#xff1a; 1、实验内容 分区分配算…

Qt 编译出的程序无法在其他电脑运行

明确构建套件&#xff08;Kit&#xff09; Kit 包含了构建程序所需的全部工具&#xff0c;例如编译器&#xff0c;可以从Qt Creator 左下角查看Kit。 我这里使用的Kit是Desktop Qt 5.12.6 MinGW 64-bit 打开 Kit 版本对应的 Qt 命令行工具 我这里需要打开Qt 5.12.6 (MinGW 7.3…

php反序列化字符逃逸

php反序列化字符逃逸 php反序列化字符逃逸的原理 当开发者使用先将对象序列化&#xff0c;然后将对象中的字符进行过滤&#xff0c;最后再进行反序列化。这个时候就有可能会产生PHP反序列化字符逃逸的漏洞。 php反序列化字符逃逸分类 过滤后字符变多 过滤后字符变少 过滤后字…

Alma Linux和Rocky Linux,你会选择用哪个?

AlmaLinux和Rocky Linux是两个基于 Red Hat Enterprise Linux (RHEL) 发行版的免费开源操作系统&#xff0c;两者都旨在由社区驱动、透明且稳定&#xff0c;但两者之间存在一些关键差异。 Rocky Linux Rocky Linux 是一个基于 Red Hat Enterprise Linux (RHEL) 发行版的免费开…

Android 音视频学习之《MediaCodec》

一、介绍以及编解码流程 MediaCodec 类可用于访问低级媒体编解码器&#xff0c;即编码器/解码器组件。它是 Android 低级多媒体支持基础结构的一部分&#xff08;通常与MediaExtractor、MediaSync、MediaMuxer、MediaCrypto、 MediaDrm、Image、Surface和一起使用AudioTrack。…

060-MySQL数据库综合应用(实现登录及注册功能源代码)

【上一讲】059-MySQL数据库综合应用(实现登录及注册功能)_CSDN专家-赖老师(软件之家)的博客-CSDN博客 本文章讲解JAVA数据库技术与MySQL数据库结合使用,利用DAO技术对数据库操作进行封装,达到高内聚低耦合,具体技术如下: 1.综合利用JAVA数据库技术,掌握Connection,St…

操作系统第四次实验-基本分页存储管理(python代码实现)

一、实验目的&#xff1a; 目的&#xff1a;熟悉并掌握基本分页存储管理的思想及其实现方法&#xff0c;熟悉并掌握基本分页存储管理的分配和回收方式。 任务&#xff1a;模拟实现基本分页存储管理方式下内存空间的分配和回收。 二、实验内容&#xff1a; 1、实验内容 内存空间…

一道有意思的图论题

今天写这道题的过程就一直在摆&#xff0c;主要是写不太出来&#xff0c;之前想到动态规划去了&#xff0c;然后又开始深搜&#xff0c;在出口那块放动态规划 题&#xff1a; D. Ela and the Wiring Wizard 点我 但是cf让我明白了一个道理&#xff0c;任何一道我写不出来的题代…

点菜方案数

题目描述 不过uim的口袋里只剩 M元(M < 10000)&#xff0c;来到了一家低端餐馆前。 餐馆虽低端&#xff0c;但是菜品种类不少&#xff0c;有 N 种(N < 100)&#xff0c;第i种卖元(ai < 1000)。由于是很低端的餐馆所以每种菜只有一份。 uim奉行“不把钱吃光不罢休”&a…

作用域与作用域链

javascript拥有一套设计良好的规则来存储变量&#xff0c;并且之后可以方便的找到这些变量&#xff0c;这套规则叫做作用域。 内部原理 内部原理分成编译、执行、查询、嵌套和异常五部分。今天来简单说一下查询。 var a2;这行代码中&#xff0c;在引擎执行的第一步操作中&am…

【C++ Primer】阅读笔记(3):decltype

目录 简介decltype基础decltype需要注意的地方1.decltype处理顶层const、引用与auto不同2.如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型。3.如果表达式的内容是解引用操作,则decltype会得到引用类型。4.对于decltype所用的表达式来说,如果变量…