单元测试——测试神器,testng
为什么用它
建议使用 TestNG 作为 Java 项目的主要单元测试框架,因为 TestNG 在参数化测试、依赖测试以及套件测试(组)方面功能更加强大。TestNG 意味着高级的测试和复杂的集成测试。它更加的灵活,特别是对大的套件测试。另外,TestNG 也涵盖了 JUnit4 的全部功能。那就没有任何理由使用 Junit了
更多细节,可以参见:JUnit 4 与 TestNG 对比
解决什么问题
- 断言结果
- 期望异常
- 进行分组
- 多线程测试
- 依赖测试
- 有测试可视化结果
即:它即能测试单元测试,也能进行集成测试,甚至也可以使用于系统测试(比较少用)。
基本概念
概论
TestNG,即Testing, Next Generation,下一代测试技术,是一套根据JUnit 和 NUnit思想而构建的利用注释来强化测试功能的一个测试框架,即可以用来做单元测试,也可以用来做集成测试
组成
- 一套测试(suite)由一个XML文件所表示。它能够包含一个或者多个测试, 标记来定义。
- test由 标记来表示一个测试,并且可以包含一个或者多个TestNG类。
- TestNG 类是包含至少一个TestNG annotation的 java类,由标签描述并包含一个或多个测试方法。
- 测试方法,就是一个普通的Java方法,在由@Test标记。
使用场景
使用场景是按注解来陈述的,没有列举全部注解,更多注解可以参见:TestNG基本注解
@BeforeClass
用于集成测试或者其他依赖的初始。比如数据库的初始
@AfterClass
用于测试的资源销毁。建议尽量不用。
@Test
用于标记需要测试的方法。一般在类里import static org.testng.Assert.*;
,这样方法的时候更优雅。
断言
在方法里,通过assertXxx系列来断言结果
@Test
public void assertResult() {
String result = "result";
//断言结果值等于
assertEquals("result", result);
boolean isTrue = true;
//断言结果真假
assertTrue(isTrue);
//其他的asertXxx系统自行查看API
}
异常
通过expectedExceptions属性来捕获异常
@Test(expectedExceptions = BusinessException.class)
public void expectedException() {
Iterator i = mock(Iterator.class);
when(i.next()).thenThrow(BusinessException.class);
i.next();
}
线程
通过invocationCount和threadPoolSize属性来实现。
@Test(invocationCount = 8, threadPoolSize = 3)
public void testThread() {
long threadId = Thread.currentThread().getId();
System.out.println("线程号为:" + threadId);
}
执行结果
[ThreadUtil] Starting executor timeOut:0ms workers:8 threadPoolSize:3
线程号为:12
线程号为:13
线程号为:11
线程号为:12
线程号为:11
线程号为:13
线程号为:12
线程号为:13
PASSED: testThread
PASSED: testThread
PASSED: testThread
PASSED: testThread
PASSED: testThread
PASSED: testThread
PASSED: testThread
PASSED: testThread
依赖
通过dependsOnMethods、dependsOnGroups来实现。
@Test
public void preAction() {
System.out.println("preAction");
}
@Test(dependsOnMethods = "preAction")
public void action() {
System.out.println("action");
//dependsOnGroups就不再做试验了
}
执行结果:
preAction
action
PASSED: preAction
PASSED: action
忽略
通过enable来实现
@Test(enabled=false)
public void disable(){
//建议少用
System.out.println("暂时不执行");
}
分组
通过groups来实现
@Test(groups = "database")
public void update() {
IDbDao dbDao = mock(IDbDao.class);
UserEntity user = new UserEntity();
when(dbDao.fetch(UserEntity.class, 1L)).thenReturn(user);
UserEntity fetchUser = dbDao.fetch(UserEntity.class, 1L);
assertEquals(user, fetchUser);
}
测试报告
测试报告是测试非常重要的部分.
TestNG默认情况下,会生产两种类型的测试报告HTML的和XML的。 测试报告位于 "test-output" 目录下.