TestNG 官网地址:http://testng.org/doc/
TestNG是一个测试框架的灵感来自JUnit和NUnit,但引入一些新的功能,使它更强大和更容易使用,如:
本教程基于 IntelliJ IDEA 和 Maven ,所以,这里只介绍 Maven 的安装方式。
org.testng
testng
6.13
test
通过 IntelliJ IDEA 创建 FirstTest 测试类。编写如下代码:
import org.testng.annotations.Test;
import static org.testng.AssertJUnit.assertEquals;
public class FirstTest {
@Test
public void testCase(){
assertEquals(2+2, 4);
}
}
通过 @Test 注解一个方法为测试用例。
通过 assertEquals() 方法来断言两个数是否相等。
运行测试:
===============================================
Default Suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
我们先感官上对TestNG使用有一个初步认识。
Test Fixture 是指一个测试运行所需的固定环境,准确的定义:
The test fixture is everything we need to have in place to exercise the SUT
在进行测试时,我们通常需要把环境设置成已知状态(如创建对象、获取资源等)来创建测试,每次测试开始时都处于一个固定的初始状态;测试结果后需要将测试状态还原,所以,测试执行所需要的固定环境称为 Test Fixture。
表:
注解 | 说明 |
---|---|
@BeforeSuite | 注解的方法在测试套件(中的所有用例)开始前运行一次 |
@AfterSuite | 注解的方法在测试套件(中的所有用例)结束后运行一次。 |
@BeforeClass | 注解的方法在当前测试类(中所有用例)开始前运行一次。 |
@AfterClass | 注解的方法在当前测试类(中所有用例)结束后运行一次。 |
@BeforeTest | 对于套件测试,在运行属于标签内的类的所有测试方法之前运行。 |
@AfterTest | 对于套件测试,在运行属于标签内的类的所有测试方法之后运行。 |
@BeforeGroups | 在调用属于该组的所有测试方法之前运行。 |
@AfterGroups | 在调用属于该组的所有测试方法之后运行。 |
@BeforeMethod | 注解的方法将在每个测试方法之前运行。 |
@AfterMethod | 注释的方法将在每个测试方法之后执行。 |
接下来通过例子演示上面部分注解的用法。
import org.testng.annotations.*;
public class FixtureTest {
//在当前测试类开始时运行。
@BeforeClass
public static void beforeClass(){
System.out.println("-------------------beforeClass");
}
//在当前测试类结束时运行。
@AfterClass
public static void afterClass(){
System.out.println("-------------------afterClass");
}
//每个测试方法运行之前运行
@BeforeMethod
public void before(){
System.out.println("=====beforeMethod");
}
//每个测试方法运行之后运行
@AfterMethod
public void after(){
System.out.println("=====afterMethod");
}
@Test
public void testCase1(){
System.out.println("test case 1");
}
@Test
public void testCase2(){
System.out.println("test case 2");
}
}
运行上面的测试,执行结果如下。
-------------------beforeClass
=====beforeMethod
test case 1
=====afterMethod
=====beforeMethod
test case 2
=====afterMethod
-------------------afterClass
===============================================
Default Suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
TestNG 与 Junit 比较大的一个差异就是前者通过 testng.xml 文件来配置测试用例的执行。 testng.xml文件可以很好的控制要执行的测试用例的粒度,及各种运行策略。
目前testng.xml DTD(Document Type Definition; DTD是一种XML的约束方式。) 配置说明可以在:这里
测试项目目录结果如下:
testng.xml 配置文件如下:
在 testng.xml 文件上右键点击运行测试。
运行结果如下:
在我们创建测试用例时,大概分三个层级。
接下来介绍,如何控制这三个级别用例的执行。当然,核心还是通过 testng.xml 文件配置。
指定测试类的运行,上一节已经介绍。
注意: 测试方法
有时候我们的测试用例并不想以测试包、类和用例为单位去运行。测试用例可以有多个纬度去标识。
例如,可以根据用例的重要程度划分:
重要程度:低——>中——>高
或者,根据用例的类型划分:
类型:正常——>异常
TestNG 允许我们给测试用例贴标签。我们可以根据这些标签有选择地的跳过或执行这些用例。
import org.testng.annotations.Test;
import static org.testng.AssertJUnit.assertEquals;
@Test(groups = {"功能测试"})
public class TagTest {
@Test(groups={"高", "正常"})
public void testCase1(){
assertEquals(2+2, 4);
}
@Test(groups = {"高", "正常"})
public void testCase2(){
assertEquals(5-3, 2);
}
@Test(groups = {"中", "正常"})
public void testCase3(){
assertEquals(2/1, 2);
}
@Test(groups = {"低", "异常"})
public void testCase4(){
assertEquals(2/0, 1);
}
}
接下来配置 testng.xml ,根据标签筛选要运行的测试用例。
不要忘了,我们给 TagTest 测类同样也划分了组(groups = {"功能测试"}),现在修改 testng.xml 配置。
……
……
再次运行测试:testCase1、testCase2 和 testCase3 三条用例将被执行。
有时候,我们希望用例按照我们要求的顺序来执行。TestNG 同样可以满足这一点要求。
import org.testng.annotations.Test;
import static org.testng.AssertJUnit.assertEquals;
public class CaseRunTest {
@Test
public void testCase1(){
assertEquals(2+2, 4);
}
@Test
public void testCase2(){
assertEquals(2+2, 4);
}
@Test
public void testCase3(){
assertEquals(2+2, 4);
}
}
通过 testng.xml 文件修改配置。
不设置的情况下默认为 true 。
当某一条用例运行失败时,其它用例必然也会失败,所以,我们就没有必要再运行其它用例了,这个时候我们就可以设置用例之间的依赖。
import org.testng.annotations.Test;
import static org.testng.AssertJUnit.assertEquals;
public class DependentMethodsTest {
@Test
public void testAdd1(){
assertEquals(3+1, 5);
}
@Test(dependsOnMethods = {"testAdd1"})
public void testAdd2(){
assertEquals(3+2, 5);
}
}
import org.testng.annotations.Test;
import static org.testng.AssertJUnit.assertEquals;
public class DependentGroupsTest {
@Test(groups={"funtest"})
public void testAdd1(){
assertEquals(3+1, 5);
}
@Test(groups={"funtest"})
public void testAdd2(){
assertEquals(3+2, 5);
}
@Test(dependsOnGroups = {"funtest"})
public void testAdd3(){
assertEquals(3+2, 5);
}
}
参数化也测试用例中常用的技巧之一,它可以增加用例的可配置性和减少相同用例的编写。
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import static org.testng.AssertJUnit.assertEquals;
public class DataProviderTest {
@Test
@Parameters({"add1","add2","result"})
public void testAdd1(int add1, int add2, int result){
assertEquals(add1+ add2, result);
}
}
具体的测试数据在 testng.xml 文件中设置。
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.AssertJUnit.assertEquals;
public class DataProviderTest {
// 定义对象数组
@DataProvider(name = "add")
public Object[][] Users() {
return new Object[][] {
{ 3, 2, 5 },
{ 2, 2, 4 },
{ 3, 3, 7 },
};
}
@Test(dataProvider="add")
public void testAdd2(int add1, int add2, int result){
assertEquals(add1+add2, result);
}
}
在 testAdd2() 中通过 dataProvider="add" 调用定义的对象数组,并通过参数获取相应的测试数据。
执行结果如下:
TestNG 是我接触过的唯一自身支持多程技术的单元测试框架。虽然代码级别的单元测试运行得很快,多线程的意义并不大。但如果是UI自动化测试的话运行速度就会非常慢,这个时候多线程技术就会变得很重要。
这里只介绍 testng.xml 文件,其中的使用到的测试用例,请参考前面的章节创建。
parallel 设置多线程的级别划分。
parallel=“methods”: TestNG将在不同的线程中运行所有的测试方法。依赖方法也将在单独的线程中运行,但它们将尊重你指定的顺序。
parallel=“tests”: TestNG 将在同一个线程中运行相同的标记的所有方法,但是每个标记将在一个单独的线程中。这允许你将所有非线程安全的类分组在同一个中,并保证它们将在同一个线程中运行,同时利用尽可能多的线程来运行测试。
parallel=“classes”: TestNG将在同一个线程中运行同一个类中的所有方法,但是每个类都将在一个单独的线程中运行。
parallel=“instances”: TestNG将在同一个线程中运行相同实例中的所有方法,但是在两个不同实例上的两个方法将在不同的线程中运行。
thread-count 用于指定线程的个数。
(十一)TestNG 其他使用技巧
除了前面介绍的功能外,TestNG 还有一些使用技巧,相对比较简单,这里通过一个例子来演示。
1、其它使用技巧
import org.testng.annotations.Test;
import static org.testng.AssertJUnit.assertEquals;
public class OtherTest {
// 该条用例跳过执行
@Test(enabled = false)
public void testCase1(){
assertEquals(2+2, 4);
}
// 设定用例超时时间
@Test(timeOut = 3000)
public void testCase2() throws InterruptedException {
Thread.sleep(3001);
}
// 预设用例抛出的异常类型
@Test(expectedExceptions = RuntimeException.class)
public void testCase3(){
assertEquals(2/0,1);
}
}
enabled 设置用例是否跳过执行,默认为:true ,表示不跳过。false 表示跳过执行。
timeOut 设置用例运行的超时间,3000 单位为毫秒,当用例运行时间超过 3000 毫秒则判定为失败。不管用例本身是否运行失败。
expectedExceptions 用来预设用例运行会出现的异常。例如 2⁄0 将会抛出 RuntimeException 类型的异常,如果出现异常则表示用例执行成功。
(十二)TestNG 生成测试报告
TestNG 默认自带的有HTML格式的测试报告。这也充分说明拿它来做 UI 自动化测试的优势。
1、通过 Maven 生成报告
切换到 TestngTest 项目的跟目录下,通过 mvn test 命令运行测试。
TestngTest> mvn test
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building TestngTest 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ TestngTest
--- [WARNING] Using platform encoding (GBK actually) to copy filtered resources,
i.e. build is platform dependent!
[INFO] Copying 0 resource
...
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running TestSuite
Configuring TestNG with: org.apache.maven.surefire.testng.conf.TestNG652Configurator@104e3b2
Tests run: 19, Failures: 5, Errors: 0, Skipped: 2, Time elapsed: 3.862 sec <<< FAILURE!
在该系列教程开始前,我已经说明了整个项目基于 Maven 创建。
现在打开 ..\TestngTest\target\surefire-reports\index.html 将会看到整个项目的运行结果。
2、通过 IntelliJ IDEA 生成测试报告
在 IntelliJ IDEA 中默认运行测试用例是不会生成HTML报告的,需要进行简单的配置。
菜单栏: “Run” –>“Edit Configuraction…” 。
如上图,选择运行测试用例的 testng.xml 文件–>“Configuration”–>“Listeners”–> 勾选“Use default reporters” 选项, 最后点击“OK” 按钮, 完成设置。
好了! 现在用 IntelliJ IDEA 运行 TestNG 测试用例一样可以生成报告了。