# TestNG单元测试
# TestNG
* 官网:[https://testng.org](https://testng.org/)
* TestNG 是一个测试 Java 应用程序的新框架,相比于JUnit更加强大、创新、可扩展、灵活
* 更全面
* 更适合隔离性强的单元测试
* 更适合复杂的集成测试
## Maven引入使用
~~~
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<!-- 最新版本自己查询修改 -->
<version>7.3.0</version>
<scope>test</scope>
</dependency>
~~~
## IDEA生成单元测试
* 进入指定代码`.java`类文件,代码中任意位置右键`Genertate-Tests`,勾选要生成的方法即可,后续自行完善具体测试方法
![](https://ooo.0o0.ooo/2020/05/29/4abesTqOmN19R6x.png)
## 注解使用
| 注解 | 描述 |
| --- | --- |
| @Test | 将类或方法标记为测试的一部分 |
| @BeforeTest | 注释的方法将在属于标签内的类的所有测试方法运行之前运行 |
| @AfterTest | 注释的方法将在属于标签内的类的所有测试方法运行之后运行 |
| @BeforeMethod | 注释方法将在每个测试方法之前运行 |
| @AfterMethod | 注释方法将在每个测试方法之后运行 |
| @BeforeClass | 在调用当前类的第一个测试方法之前运行,注释方法仅运行一次 |
| @AfterClass | 在调用当前类的第一个测试方法之后运行,注释方法仅运行一次 |
| @BeforeGroups | 配置方法将在之前运行组列表。 此方法保证在调用属于这些组中的任何一个的第一个测试方法之前不久运行 |
| @AfterGroups | 此配置方法将在之后运行组列表。该方法保证在调用属于任何这些组的最后一个测试方法之后不久运行 |
| @BeforeSuite | 在该套件的所有测试都运行在注释的方法之前,仅运行一次 |
| @AfterSuite | 在该套件的所有测试都运行在注释方法之后,仅运行一次 |
| @DataProvider | 标记一种方法来提供测试方法的数据。 注释方法必须返回一个Object \[\] \[\],其中每个Object \[\]可以被分配给测试方法的参数列表。 要从该DataProvider接收数据的@Test方法需要使用与此注释名称相等的dataProvider名称 |
| @Factory | 将一个方法标记为工厂,返回TestNG将被用作测试类的对象。 该方法必须返回Object \[\] |
| @Listeners | 定义测试类上的侦听器 |
| @Parameters | 描述如何将参数传递给@Test方法 |
> 注解的基本使用此处不再详细讲解,网上也有大量资料教程,注意各注解组合使用顺序即可
### 忽略测试
~~~
@Test(enabled = false)
public void ignore(){
System.out.println("忽略执行");
}
~~~
### 组测试
~~~
@Test(groups = "server")
public void test1(){
System.out.println("这是服务端组的测试方法");
}
@Test(groups = "client")
public void test2(){
System.out.println("这是客户端组的测试方法");
}
@BeforeGroups("server")
public void beforeGroupsOnServer(){
System.out.println("这是服务端组运行之前运行的方法");
}
@AfterGroups("client")
public void afterGroupsOnClient(){
System.out.println("这是客户端组运行之后运行的方法");
}
~~~
### 异常测试
~~~
@Test(expectedExceptions = RuntimeException.class)
public void runTimeExceptionSuccess(){
System.out.println("这是我的异常测试");
throw new RuntimeException();
}
~~~
### 依赖测试
~~~
@Test
public void test1(){
System.out.println("test1 run");
}
@Test(dependsOnMethods = {"test1"})
public void test2(){
System.out.println("test2 run");
}
~~~
### 参数化测试
* `cn.exrick.testng.ParamterTest.java`
~~~
@Test
@Parameters({"name", "age"})
public void paramTest1(String name, int age){
System.out.println("name = " + name + "; age = " + age);
}
~~~
* `resources`文件夹中添加`Paramter.xml`文件
~~~
<?xml version="1.0" encoding="UTF-8" ?>
<suite name="parameter">
<test name="param">
<classes>
<parameter name="name" value="exrick"/>
<parameter name="age" value="18"/>
<class name="cn.exrick.testng.ParamterTest"/>
</classes>
</test>
</suite>
~~~
### 参数测试
~~~
@Test(dataProvider = "data")
public void testDataProvider(String name, int age){
System.out.println("name =" + name +"; age=" + age);
}
@DataProvider(name="data")
public Object[][] providerData(){
Object[][] o = new Object[][]{
{"zhangsan", 10},
{"lisi", 20},
{"wangwu" ,30}
};
return o;
}
@Test(dataProvider = "methodData")
public void test1(String name, int age){
System.out.println("test1方法 name="+name+";age="+age);
}
@Test(dataProvider = "methodData")
public void test2(String name, int age){
System.out.println("test2方法 name="+name+";age="+age);
}
@DataProvider(name="methodData")
public Object[][] methodDataTest(Method method){
Object[][] result=null;
if(method.getName().equals("test1")){
result = new Object[][]{
{"zhangsan", 20},
{"lisi", 25}
};
} else if (method.getName().equals("test2")) {
result = new Object[][]{
{"wangwu", 50},
{"zhaoliu", 60}
};
}
return result;
}
~~~
### 多线程测试
~~~
@Test(invocationCount = 10, threadPoolSize = 3)
public void test(){
System.out.printf("Thread Id : %s%n", Thread.currentThread().getId());
}
~~~
### 超时测试
~~~
@Test(timeOut = 3000)
public void testSuccess() throws InterruptedException {
Thread.sleep(2000);
}
~~~
- 前言版本&说明
- 概念
- Tceon-PERFOOT 是什么?
- 系统架构
- 主要使用的开源组件
- 角色控制访问权限(RBAC)
- 用户手册
- 系统配置
- 工作流使用配置
- 定时任务调度
- 项目本地运行
- 后端运行
- 前端运行
- 项目结构说明
- 附:使用Oracle等数据库
- 模块化版本
- 后端开发指南
- 基本开发指南
- 前后端数据交互标准
- 工具类及数据权限
- 代码生成器
- 增删改查CRUD
- 日志类型注解扩展
- 逻辑删除
- 各验证码使用及配置
- 前端开发指南
- 基本开发指南
- 主题/Logo/首页等配置
- 路由菜单配置
- 多语言国际化配置
- 自定义图标icon
- 工具类及数据获取
- 完整版开发指南
- 前端Vue代码生成器
- Activiti工作流
- 单点登录配置
- MinIO对象存储服务搭建
- 第三方社交账号配置
- 短信开发/站内消息/邮件
- Vaptcha验证码
- 禁用词使用
- Monaco代码编辑器
- 开放平台及单点登录
- 开放平台使用指南
- Web接入开发流程
- 单点登录开发指南
- 微信小程序端开发指南
- 项目导入与开发必读
- 通用方法工具类说明
- Uniapp端开发指南
- APP后端开发指南
- Uniapp前端开发指南
- 开发新功能示例
- 后端开发新模块
- 前端开发新页面
- 测试
- SonarQube代码质量管理
- TestNG单元测试
- ExtentReports测试报告
- Selenuim自动化Web测试
- Appuim自动化App测试
- JMeter压测性能测试
- 部署
- Spring Boot配置
- 快速部署
- 后端部署
- 前端部署
- 前端部署优化
- Docker容器化部署
- 服务器配置
- DevOps环境搭建
- 组件安装列表
- 开发设计规范
- 分支管理
- 数据库设计规范
- Redis使用规范
- Java基础开发规范
- Rest API规范
- 项目结构规范
- 前端开发规范
- 前端设计规范
- 项目搭建分享
- 后端相关
- SpringBoot 2.x区别总结
- Spring Security整合JWT
- Spring Security动态权限管理
- Spring Boot 2.x整合Quartz
- Spring Boot 2.x整合Websocket
- Spring Boot 2.x整合Activiti工作流以及模型设计器
- Spring Boot + Security全局跨域配置
- 前端相关
- axios请求封装 统一异常处理
- 动态路由菜单加载
- 多维度控制权限至按钮显示
- 发送消息图标红点实时显示
- 动态组件单页操作
- 常见问题