TestNG 单元测试详解
1、测试环境
jdk1.8.0 121
myeclipse-10.0-offline-installer-windows.exe
TestNG 插件
org.testng.eclipse 6.8.6.20130607 0745
2、介绍
套件(suite):由一个 XML 文件表示,通过<suite>标签定义,包含一个或更多测试(test)。测试(test):由<test>定义,包含一个或更多 TestNG 类(class)。TestNG类(class):至少包含一个TestNG注释(annotation)的java 类,由<class>标签定义,包含一个或多个测试方法(test medthod)。测试方法(test method):一个附注了@Test 的 java 方法。
3. Annotation


更多解释,可以查看官方文档的介绍
4、testng.xml介绍
4.1.例 1

注:test-output是运行后自动生成的。xmltest.xm1是在对应目录下新建的,testng-1.0.dtd 也是下载后,手动放进去的。
Test1.java 代码:
package unittests;
import org.testng.annotations.*
public class Test1 {
@Test
public void func1(){System.out.println("test in func1");
public void func2(){System.out.println("test in func2");

testng-1.0.dtd下载地址:http://testng.org/testng-1.0.dtd
右键 xmltest.xml-> Run As TestNG Suite,运行套件,输出如下:

说明:
1、只有被附注了@Test 的方法才会被执行。
2、如果右键只能看到 Run As Run Configurations,则右键项目,选择 refresh 刷新
3、TestNG 类没有归属 package,也可以如下编写 xml(当前版本的插件是不允许新建TestNG Class 时不提供包名的,通常建议提供包名)

4.2.例 2
也可以指定包名,而非类名,TestNG将查找 unittests 包中所有 class,且仅保留携带TestNG 注解的类。

运行结果同上
4.3.例3
还可以指定需要包含/排除的 group 和方法。
修改 Test1.java 代码
package unittests;
import org.testng.annotations.*;
public class Test1 {@Test(groups={"functest","checkintest"})public void func1(){System.out.println("test in func1");
@Test(groups={"functest""checkintest"})
public void func2(){
System.out.println("test in func2");
@Test(groups={"functest"})public void func3(){System.out.println("test in func3");
问题:保存代码后,编辑器中,代码 package unittests;右侧会提示“红叉”解决方法:




修改 xmltest.xml


运行结果:未执行任何一个测试方法。
再修改下,把


说明:
1、例中的<include>和<exclude>是 and 关系,而非 or 的关系
2、仅提供 groups 元素配置,不提供 class 元素,执行后不调用任何测试方法
3、还可以为 group 添加其它属性,比如是否并发运行,使用多少线程,是否运行Junit


运行结果:只执行了 func1 测试方法
说明:
同时设置了groups 和method元素,且同时为groups和method设置了include、exclude为 method 元素设置 include 属性,那么 groups 元素的设置不起作用,仅执行 method中需要 include 的方法
只为method元素设置exclude属性,那么根据groups 元素设置得出需要运行的测试方法然后在此基础上过滤掉 method 元素的 exclude 属性设置的方法。
4.4.例 4
默认的,TestNG 依据出现在 xm1 中的顺序执行测试。可以设置 preserve-order 属性为false 来改变这一行为。
修改xmltest.xml如下

5.测试方法(Test method),测试类(Test class),测试组(Test groups)
5.1.测试方法(Test method)
默认的,被附注了@Test 的测试方法,其返回值被忽略,除非设置 allow-return-values值为 true。
<suite allow-return-values="true">
or
<test allow-return-values="true">
5.2.测试组(test groups)
groups 可以位于<test>、<suite>元素内。如果在<suite>标签下指定 groups,那么 group设置作用于该 suite 下的所有<test>。
5.2.1.例 1
修改 Test1.java 内容下
package unittests;
import org.testng.annotations.*
public class Test1 {@Test(groups={"functest","checkintest"})public void testMethod1(){System.out.println("test in func1");
@Test(groups={"functest","checkintest"})public void testMethod2(){System.out.println("test in func2");
@Test(groups={"functest"})public void testMethod3(){System.out.println("test in func3");
groups 元素放在<test>标签下


groups 元素放在<suite>标签下

5.2.2.例 2
使用正则表达式。
修改 Test1.java 内容下
package unittests;
import org.testng.annotations.*;
public class Test1 {
@Test(groups={"windows.functest"})public void testMethod1(){System.out.println("test in func1");
@Test(groups={"linux.functest"})public void testMethod2(){System.out.println("test in func2");
@Test(groups={"functest"})public void testMethod3(){System.out.println("test in func3");
修改 xmltest.xml如下

运行结果:
只执行了 testMethod1
5.2.3.例 3
方法组(method groups)包含、排除单个测试方法修改 xmltest.xm1 内容如下:


运行结果:testMethod1,testMethod2,testMethod3 都被执行了。
嵌套组
组可以包含组。
修改 Test1.java 如下
package unittests;
import org.testng.annotations.*;
public class Test1 {@Test(groups={"functest","checkintest"})public void testMethod1(){System.out.println("test in func1");
@Test(groups={"functest","checkintest"})public void testMethod2(){System.out.println("test in func2");
@Test(groups={"functest"})public void testMethod3(){System.out.println("test in func3");
修改xmltest.xm1


运行结果:
3个测试方法都被执行了,为何?难道是 bug?不理解
排除组

运行结果:
只执行了 testMethod3 测试方法
Partial 组
可在 class级别添加组,然后在方法级别添加组修改 Test1.java 内容如下
package unittests;
import org.testng.annotations.*.
@Test(groups="functest")
public class Test1 {
@Test(groups={"checkintest"})public void testMethod1(){System.out.println("test in func1");
@Test(groups={"checkintest"})public void testMethod2(){System.out.println("test in func2");
@Test
public void testMethod3(){System.out.println("test in func3");
xmltest.xml 内容如下

运行结果:仅执行了 testMethod3
说明:TestNG类中所有被附注了@Test的测试方法,默认都归属在类级别定义的group
6. 参数
6.1.来自 testng.xml 的参数
6.1.1.例 1
修改 Test1.java

修改 xmltest.xml

![]()

参数还可以用于@Before/After 和@Factory
6.1.2.例 2可用@0ptional 来声明参数可选
修改 Test1.java

说明:如果在 xm1 文件中找不到参数 arg_in_xm1,那么使用 0ptional 括号中的值作为参都
修改 testxml.xm1


6.2.携带 DataProvider 的参数
6.2.1.例 1
修改 Test1.java


注意:必须用 dataProvider 属性指明 Data Provider,属性值必须和@DataProvider(name="...")中 name 的值保持一致。另外,参数个数得保持一致。
修改 xmltest.xm1

运行结果,输出如下数据:
rebort 36
2014 37
默认的,TestNG 会在当前测试类、其某个父类中査找 Data Provider。如果想把 dataprovider 放在其它的类中,那么被附注的方法必须是静态方法、或者携带无参构造器的类,并在 dataProviderClass 属性中指定该类。
6.2.2.例 2
在 unittests 包下新建一个 StaticProvider.java,代码内容如下



运行结果,输出:
42
data provider 返回以下类型之一:
1)返回一个 object[][],数组第一维度的大小,代表了测试方法被调用的次数,第二维度则包含了和测试方法的参数类型匹配的任意对象数组。
2)返回一个迭代器 Iterator<0bject[]>。
eg:
@DataProvider(name ="test1")public Iterator<Object[]>createData(){return new MyIterator(DATA);
6.2.3.例 3
如果声明@DataProvider接收一个java.lang.reflect.Method作为第一个参数,TestNG将会把当前测试方法传递给该参数。
修改 Test1.java 内容如下


如果想在不同的线程池中运行多个 data provider,需要从 xm1 文件中运行它们。
7. 依赖
7.1.使用注解的依赖
7.1.1.例 1
依赖方法
修改 Test1.java 内容如下


运行结果,先后输出:test2
test1
说明:test1的运行依赖 test2 的运行注意:这种依赖,如果被依赖者运行失败,那么依赖者的不被执行,报告中被标记为 SKIPeg:修改 test2方法如下,再次运行


7.1.2.例 2
利用@Test 的属性设置 alwaysRun=true 解决例2中被依赖者运行失败,不执行依赖者的
问题
修改 Test1.java


7.1.3.例 3
依赖组


更多资料参考: Otaku – Cedric's blog
默认的,依赖方法按组分类,如果方法 test1 和方法 test2 都是同一个测试类的测试方法,test1依赖test2,那么当该类的多个实例被调用时,会先执行完所有test2,再执行test1.
7.1.4.例 4
新建 testNG 测试类





运行结果


运行结果

7.2.XML 中的依赖
可选的,可在 testng.xm1 文件中指定组依赖。使用<dependencies>标签来实现这个。修改 Test1.java 内容如下



修改 xmltest.xml 内容如下

注意:被依赖的多个组之间用空格分隔。
8. 工厂模式
动态的创建测试。
8.1.例1
假设,你想创建一个测试方法,使用不同的值,多次访问某个web站点的页面


如果继续按这个思路继续,很快就会变得难以管理。所以考虑使用工厂模式新建 TestNG 类文件 WebTest.java

新建 TestNG 类文件 WebTestFactory.java


修改 xmltest.xml 如下

运行结果:webTest 中的测试方法也被执行了
说明:附注@Factory 注解的方法中构造某测试类的实例,会自动调用该测试类中带有@Test注解的方法
当然,也可以在 java 程序中通过代码来运行新建 Test2.java,内容如下:

factory 方法接收类似@Test 和@Before/After 的参数,且必须返回 0bject[]。返回的对象可以是任何类实例(注:对象所在类,不含@xxxx注解的方法不被执行)。
@Factory 也可以配合 data provider 使用,可用于构造器或者普通方法
8.2.例 2
修改 WebTestFactory.java 内容如下


结果:运行了 30 次测试,即 testServer 被调用了 38 次。
9.类级别的注解



运行结果:test1,test2都被执行了,也就是说类级别的@Test 注解会把该类的所有公有方法都当作测试方法,不管是否有注解。这种情况下,依旧可为单个类方法进行注解以添加其他属性,比如归属的组别
10.并行和超时
10.1. 并行套件
假如有多个套件需要运行。修改 xmltest.xml如下,复制xmltest.xml分别为xmltest2.xml,xmltest3.xml,修改套件名分别为suite2,suite3


注意:要先 javac 对类文件进行编译,否则会报错,类似如下:ITestNG] [ERROR]
Cannot find class in classpath:unittests.Test1
运行套件

且想让每个套件在单独的线程中运行,可添加-suitethreadpoolsize选项java org.testng.TestNG -suitethreadpoolsize 3 testng.xml testng2.xmltestng3.xml
10.2.并行test,class,method
略
11.返回失败测试
TestNG 会为每次运行套件失败的测试,在结果输出目录(如果为用 -d outpu_dir 指定目录则结果输出目录为在当前工作目录下的生成的 test-outputs)下创建一个名为testng-failed.xm1 的文件。可按如下方式运行失败的用例。src>java org.testng.TestNG test-output/testng-failed.xml
12.JUnit tests

13.Annotation 转换略
14.Method Interceptors略
15. TestNG Listeners
哈
16. Dependency injection
贻
17.重写测试方法
略
18.更改套件、方法略
19.通过编程方式运行 TestNG




假设想同运行如下假设的 xm1 一样,通过编程方式运行 TestNG 可如下操作



20.测试结果
20.1. 成功,失败断言
20.1.1.例 1
修改 Test1.java 内容如下

为了满足更复杂对象的断言,可导入 JUnit 的 Assert 类。20.1.2.例 2
修改 Test1.java 内容如下


注意:使用 static import 是为了在使用断言方法,如 assertEquals 时,不用携带包名类名,如果不用 static,则需要这么使用:org.testng.AssertJUnit.assertEquals
20.2. Logging和结果
20.2.1.logging 监听器
例:



运行结果

说明:
1、-listener 选项指定使用的监听器
也可以在 xm1 中指定监听器修改 xmltest.xm1 内容如下


运行结果:

意:命令行运行,testng 自带的 assert 似乎不起作用,为何?
还可以在.java 文件中指定



注:如果同时在.java 代码中和 xm1中指定同一个监听器,则针对每个测试方法的测试结果,会运行两次 1og 方法
20.2.2.Logging Reporters略
20.2.3.JUnitReports略
20.2.4.Reporter API略
20.2.5.XML Reports略
参考连接:
http://testng.org/doc/documentation-main.htm1
相关文章:
TestNG 单元测试详解
1、测试环境 jdk1.8.0 121 myeclipse-10.0-offline-installer-windows.exe TestNG 插件 org.testng.eclipse 6.8.6.20130607 0745 2、介绍 套件(suite):由一个 XML 文件表示,通过<suite>标签定义,包含一个或更多测试(test)。测试(test):由<test>定义…...
测试100问:http和https的区别是什么?
哈喽,大家好,我是十二,今天给大家分享的问题是:http和https的区别是什么? 首先我们要知道 HTTP 协议传播的数据都是未加密的,也就是明文的,因此呢使用 http协议传输一些隐私信息也就非常不安全&…...
通过python实现bilibili缓存视频转为mp4格式
需要提前下好ffmpeg import os import fnmatch import subprocess Bilibili缓存的视频,*280.m4s结尾的是音频文件,*050.m4s结尾的是视频,删除16进制下前9个0,即为正常音/视频 使用os.walk模块,遍历每一个目录…...
高效爬虫:一文掌握 Crawlee 的详细使用(web高效抓取和浏览器自动化库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Crawlee概述1.1 Crawlee介绍1.2 为什么 Crawlee 是网页抓取和爬取的首选?1.3 为什么使用 Crawlee 而不是 Scrapy1.4 Crawlee的安装二、Crawlee的基本使用2.1 BeautifulSoupCrawler的使用方式2.2 ParselCrawler的使…...
React中 点击事件写法 的注意(this、箭头函数)
目录 1、错误写法:onClick{this.acceptAlls()} 2、正确写法:onClick{this.acceptAlls}(不带括号) 总结 方案1:构造函数绑定 方案2:箭头函数包装方法(更简洁) 方案3&am…...
【分享】Ftrans文件摆渡系统:既保障传输安全,又提供强集成支持
【分享】Ftrans文件摆渡系统:既保障传输安全,又提供强集成支持! 在数字化浪潮中,企业对数据安全愈发重视,网络隔离成为保护核心数据的关键防线,比如隔离成研发网-办公网、生产网-测试网、内网-外网等。网络…...
Day31笔记-进程和线程
一、进程和线程简介 1.概念 1.1多任务 程序的运行是CPU和内存协同工作的结果 操作系统比如Mac OS X,UNIX,Linux,Windows等,都是支持“多任务”的操作系统 问题1:什么是多任务? 就是操作系统可以同时运行多个任务。打个比方,你一边在用浏览器上网,一边在听MP3,一边…...
python每日一练
题目一 输入10个整数,输出其中不同的数,即如果一个数出现了多次,只输出一次(要求按照每一个不同的数第一次出现的顺序输出)。 解题 错误题解 a list(map(int,input().split())) b [] b.append(a[i]) for i in range(2,11):if a[i] not in b:b.append(a[i]) print(b)但是会…...
深入理解 RxSwift 中的 Driver:用法与实践
目录 前言 一、什么是Driver 1.不会发出错误 2.主线程保证 3.可重放 4.易于绑定 二、Driver vs Observable 三、使用场景 1.绑定数据到UI控件 2.响应用户交互 3.需要线程安全的逻辑 4.如何使用Driver? 1.绑定文本输入到Label 2.处理按钮点击事件 3.从网络请求…...
算法思想之前缀和(二)
欢迎拜访:雾里看山-CSDN博客 本篇主题:算法思想之前缀和(二) 发布时间:2025.4.11 隶属专栏:算法 目录 算法介绍核心思想大致步骤 例题和为 K 的子数组题目链接题目描述算法思路代码实现 和可被 K 整除的子数组题目链接题目描述算法…...
C++ - 数据容器之 unordered_map(声明与初始化、插入元素、访问元素、遍历元素、删除元素、查找元素)
一、unordered_map unordered_map 是 C STL 中的一个关联容器,它有如下特点 unordered_map 存储键值对,使用哈希表实现 unordered_map 的每个键在容器中只能出现一次 unordered_map 的存储的键值对是无序的 平均情况下,查找、插入、删除都…...
六、分布式嵌入
六、分布式嵌入 文章目录 六、分布式嵌入前言一、先要配置torch.distributed环境二、Distributed Embeddings2.1 EmbeddingBagCollectionSharder2.2 ShardedEmbeddingBagCollection 三、Planner总结 前言 我们已经使用了TorchRec的主模块:EmbeddedBagCollection。我…...
硬件知识积累 单片机+ 光耦 + 继电器需要注意的地方
1. 电路图 与其数值描述 1.1 单片机引脚信号为 OPtoCoupler_control_4 PC817SB 为 光耦 继电器 SRD-05VDC-SL-A 的线圈电压为 67Ω。 2. 需注意的地方 1. 单片机的推挽输出的电流最大为 25mA 2. 注意光耦的 CTR 参数 3. 注意继电器线圈的 内阻 4. 继电器的开启电压。 因为光耦…...
Dockerfile 学习指南和简单实战
引言 Dockerfile 是一种用于定义 Docker 镜像构建步骤的文本文件。它通过一系列指令描述了如何一步步构建一个镜像,包括安装依赖、设置环境变量、复制文件等。在现实生活中,Dockerfile 的主要用途是帮助开发者快速、一致地构建和部署应用。它确保了应用…...
MCU屏和RGB屏
一、MCU屏 MCU屏:全称为单片机控制屏(Microcontroller Unit Screen),在显示屏背后集成了单片机控制器,因此,MCU屏里面有专用的驱动芯片。驱动芯片如:ILI9488、ILI9341、SSD1963等。驱动芯片里…...
Elasticsearch 向量数据库,原生支持 Google Cloud Vertex AI 平台
作者:来自 Elastic Valerio Arvizzigno Elasticsearch 将作为第一个第三方原生语义对齐引擎,支持 Google Cloud 的 Vertex AI 平台和 Google 的 Gemini 模型。这使得联合用户能够基于企业数据构建完全可定制的生成式 AI 体验,并借助 Elastics…...
蓝桥杯基础数论入门
一.试除法 首先我们要了解,所有大于1的自然数都能进行质因数分解。试除法作用如下: 质数判断 试除法通过验证一个数是否能被小于它的数(一般是用2到用根号x)整除来判断其是否为质数。根据定义,质数只能被1和自身整除…...
Spring 事件机制与观察者模式的深度解析
一、引言 在软件设计中,观察者模式(Observer Pattern)是一种非常经典且实用的设计模式。它允许一个对象(Subject)在状态发生改变时通知所有依赖它的对象(Observers),从而实现对象之…...
【软考系统架构设计师】信息安全技术基础知识点
1、 信息安全包括5个基本要素:机密性、完整性、可用性、可控性与可审查性。 机密性:确保信息不暴露给未授权的实体或进程。(采取加密措施) 完整性:只有得到允许的人才能修改数据,并且能够判断出数据是否已…...
Python编程快速上手 让繁琐工作自动化笔记
编程基础 字符串使用单引号...
2025年第十六届蓝桥杯省赛真题解析 Java B组(简单经验分享)
之前一年拿了国二后,基本就没刷过题了,实力掉了好多,这次参赛只是为了学校的加分水水而已,希望能拿个省三吧 >_< 目录 1. 逃离高塔思路代码 2. 消失的蓝宝思路代码 3. 电池分组思路代码 4. 魔法科考试思路代码 5. 爆破思路…...
Java 设计模式:策略模式详解
Java 设计模式:策略模式详解 策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端,从…...
什么是TensorFlow?
TensorFlow 是由 Google Brain 团队开发的开源机器学习框架,被广泛应用于深度学习和人工智能领域。它的基本概念包括: 1. 张量(Tensor):在 TensorFlow 中,数据以张量的形式进行处理。张量是多维数组的泛化…...
【3GPP核心网】【5G】精讲5G网络语音业务系统架构
1. 欢迎大家订阅和关注,精讲3GPP通信协议(2G/3G/4G/5G/IMS)知识点,专栏会持续更新中.....敬请期待! 目录 1. 音视频业务 2. 消息类业务 SMS over IMS SMS over NAS 3. 互联互通架构 3.1 音视频业务互通场景 3.2 5G 用户与 5G 用户互通 3.3 5G 用户与 4G 用户的互通…...
01-算法打卡-数组-二分查找-leetcode(704)-第一天
1 数组基础理论 数组是存放在连续内存空间上的相同数据结构的集合。数组可以通过下标索引快速获取数据,因为数组的存储空间是连续的所以在删除、更新数据的时候需要移动其他元素的地址。 下图是一个数组的案例图形:【内存连续、索引小标从0开始可…...
怎么看英文论文 pdf沉浸式翻译
https://arxiv.org/pdf/2105.09492 Immersive Translate Xournal打开...
Linux 进程基础(一):冯诺依曼结构
文章目录 一、冯诺依曼体系结构是什么?🧠二、冯诺依曼体系为何成为计算机组成的最终选择?(一)三大核心优势奠定主流地位(二)对比其他架构的不可替代性 三、存储分级:速度与容量的平衡…...
RabbitMQ 深度解析:从基础到高级应用的全面指南
🐰 RabbitMQ 深度解析:从基础到高级应用的全面指南 前言📘 一、RabbitMQ 简介⚙️ 二、核心特性可靠性 🔒灵活路由 🔄高可用性 🌐多协议支持 🌍多语言客户端 💻插件机制 ὐ…...
【图灵Python爬虫逆向】题七:千山鸟飞绝
题目背景 题目地址:https://stu.tulingpyton.cn/problem-detail/7/ 这一题为中等难度 打开控制台时会发现进入无限debug,可以通过右键点击"一律不在此处暂停"来绕过这个障碍。 一、请求与响应分析 1. 请求参数分析 首先观察网络请求&…...
ubuntu 2404 安装 vcs 2018
参考ubuntu 2204 安装 vcs 2018 系统信息 Ubuntu 24.04.2 LTS ubuntu和 安装后的 vcs 花费了 22G , 其中 "安装后的 vcs" 占13G预先配置 过程 和 2204 安装 vcs 2018 不同, 其他相同 // vm-tools 的安装, 不是虚拟机不需要 sudo apt-get update sudo apt-get inst…...
