TestNG系列之--01 简介及常用注解说明TestNG系列之--02 执行顺序控制TestNG系列之--03 并行执行测试TestNG系列之--04 框架源码
一、概述
TestNG是一个开源自动化测试框架,其灵感来自JUnit和NUnit,TestNG还涵盖了整个核心的JUnit4功能,但引入了一些新的功能,使其功能更强大,使用更方便。
优势:
l 注解
l 在线程池中运行测试,并提供各种可用策略(单线程,多线程等等)
l 测试的代码是多线程安全的
l 灵活的测试配置
l 支持数据驱动的测试(使用 @DataProvider)
l 支持参数化
l 强大的执行模型(不再是 TestSuite)
l 由各种工具和插件(Eclipse,IDEA,Maven 等)支持。
l 嵌入 BeanShell 脚本以获得更大的灵活性
l 用于运行时和日志记录的缺省 JDK 函数(无依赖项)
l 应用服务器测试的依赖方法
TestNG旨在涵盖所有类别的测试:单元,接口,端到端,集成等…
二、常用注解
TestNG选择使用注解来标注测试类。大部分注解都用在方法级别上。常用的注解列举如下:
注解 | 描述 |
将会在testng定义的xml根元素里的所有方法执行之前运行。仅运行一次。 | |
将会在testng定义的xml根元素里面的所有方法执行之后运行。,仅运行一次。 | |
在调用当前类的第一个测试方法执行之前运行。仅运行一次。
| |
在调用当前类的第一个测试方法执行之后运行,仅运行一次 | |
将在属于 | |
将在属于 | |
配置方法将在之前运行组列表。 此方法保证在调用属于这些组中的任何一个的第一个测试方法之前不久运行。 | |
此配置方法将在之后运行组列表。该方法保证在调用属于任何这些组的最后一个测试方法之后不久运行。 | |
将会在当前测试类的每一个测试方法执行之前运行。 | |
将会在当前测试类的每一个测试方法执行之后运行。 | |
标记一种方法来提供测试方法的数据。 注解方法必须返回一个 | |
将一个方法标记为工厂,返回 | |
定义测试类上的侦听器。 | |
描述如何将参数传递给@Test方法。 | |
将类或方法标记为测试的一部分。 |
1. @Before\After类注解
一般可以在Before类别的注解方法里面做一些初始化动作,如实例化数据库连接、新建数据库连接池、创建线程池、打开文件流等等。然后,我们可以在After类别的注解方法里面做一些销毁动作,如释放数据库连接、销毁数据库连接池、销毁线程池或者关闭文件流等等。同一类别的不同注解会在不同的位置被调用,
下面我们以一个例子来说明上面这些注解的用法:
新建TestNGAnnotationTest
和TestNGAnnotationTest2
(TestNGAnnotationTest2
与TestNGAnnotationTest
内容一致)
public class TestNGAnnotationTest {
@BeforeSuite
public void beforeSuite() {
System.out.println(this.getClass().getName() + " beforeSuite");
}
@AfterSuite
public void afterSuite() {
System.out.println(this.getClass().getName() + " afterSuite");
}
@BeforeTest
public void beforeTest() {
System.out.println(this.getClass().getName() + " beforeTest");
}
@AfterTest
public void afterTest() {
System.out.println(this.getClass().getName() + " afterTest");
}
@BeforeClass
public void beforeClass() {
System.out.println(this.getClass().getName() + " beforeClass");
}
@AfterClass
public void afterClass() {
System.out.println(this.getClass().getName() + " afterClass");
}
@BeforeMethod
public void beofreMethod() {
System.out.println(this.getClass().getName() + " beforeMethod");
}
@AfterMethod
public void afterMethod() {
System.out.println(this.getClass().getName() + " afterMethod");
}
@Test
public void test1() {
System.out.println(this.getClass().getName() + " test1");
}
@Test
public void test2() {
System.out.println(this.getClass().getName() + " test2");
}
}
testng.xml 里面加入
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1" >
<test name="test1" >
<classes>
<class name="com.testngdemo.TestNGAnnotationTest" />
<class name="com.testngdemo.TestNGAnnotationTest2" />
</classes>
</test>
</suite>
这里给出一张图,方便更好地理解这些注解方法的执行位置:
通常,在TestNG的执行中,测试的级别由上至下可以分为suite -> test -> class -> method,箭头的左边元素跟右边元素的关系是一对多的包含关系。
这里的test指的是testng.xml中的test tag,而不是测试类里的一个 @Test。测试类里的一个 @Test实际上对应这里的method。所以我们在使用 @BeforeSuite、 @BeforeTest、 @BeforeClass、 @BeforeMethod这些标签的时候,它们的实际执行顺序也是按照这个级别来的。
2. @Test 注解
@Test 注解是TestNG的核心注解,被打上该注解的方法,表示为一个测试方法,类比JUnit是一个道理(JUnit也是用了这个注解,在使用TestNG时候注意导包别导错)。
这个注解有多个配置属性,用法为:
@Test(param1 = ..., param2 = ...)
常见取值说明如下:
- alwaysRun : 如果=true,表示即使该测试方法所依赖的前置测试有失败的情况,也要执行
- dataProvider : 选定传入参数的构造器。(@DataProvider注解将在后面章节介绍)
- dataProviderClass : 确定参数构造器的Class类。(参数构造器首先会在当前测试类里面查找,如果参数构造器不在当前测试类定义,那么必须使用该属性来执行它所在的Class类)
- dependsOnGroups : 确定依赖的前置测试组别。
- dependsOnMethods : 确定依赖的前置测试方法。
- description : 测试方法描述信息。(建议为每个测试方法添加有意义的描述信息,这将会在最后的报告中展示出来)
- enabled : 默认为true,如果指定为false,表示不执行该测试方法。
- expectedExceptions : 指定期待测试方法抛出的异常,多个异常以逗号(,)隔开。
- groups : 指定该测试方法所属的组,可以指定多个组,以逗号隔开。组测试的用法将在后面文章单独介绍。
- invocationCount : 指定测试方法需要被调用的次数。
- invocationTimeOut : 每一次调用的超时时间,如果invocationCount没有指定,该参数会被忽略。应用场景可以为测试获取数据库连接,超时就认定为失败。单位是毫秒。
- priority : 指定测试方法的优先级,数值越低,优先级越高,将会优先与其他数值高的测试方法被调用。(注意是针对一个测试类的优先级)
- successPercentage : 此方法预期成功的百分比
- singleThreaded : 如果设置为true,则保证此测试类上的所有方法在同一线程中运行,即使当前测试正使用 parallel=“methods” 运行。此属性只能在类级别使用,在方法级别使用,则被忽略
- timeout : 指定整个测试方法的超时时间。单位是毫秒。
- threadPoolSize : 此方法的线程池大小。该方法将从 invocationCount 指定的多个线程中调用。注意:如果未指定invocationCount,则忽略此属性
下面我们写一个简单的测试类,说明@Test注解的使用以及属性的配置方式:
import org.testng.annotations.Test;
public class TestAnnotationPropertiesTest {
@Test(priority = 1, invocationCount = 3)
public void test1() {
System.out.println("invoke test1");
}
@Test(priority = 2, invocationCount = 2)
public void test2() {
System.out.println("invoke test2");
}
}
3. @Parameters 注解
@Parameters 注解用于为测试方法传递参数。
- 在任何已经有 @Test,@Before / After 或 @Factory 注解的方法上,都可以使用该注解。
- 一次只能设置一组参数值,参数按照注解中的顺序映射到 Java 方法的入参中,如果个数不匹配,TestNG 将报错;
- 参数存在作用域。在 testng.xml 中,可以放在 suite 标记下或 test 下 。如果在两个地方声明相同名称的参数,则 test 级别参数将优先于 suite 级别参数。
用法如下所示:
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class AnnotationParametersTest {
@Parameters(value = {"param1", "param2"})
@Test
public void test(String arg1, String arg2) {
System.out.println("use @Parameters to fill method arguments : arg 1 = " + arg1 + ", arg2 = " + arg2);
}
}
testng.xml配置
<test name="testAnnotationParameters">
<parameter name="param1" value="value1"></parameter>
<parameter name="param2" value="value2"></parameter>
<classes>
<class name="com.testngdemo.AnnotationParametersTest" />
</classes>
</test>
4. @DataProvider 注解
上面的小结提到@Parameters
注解可以为测试方法传递参数,但是这种方式参数值需要配置在testng.xml
里面,灵活性不高。而@DataProvider
注解同样可以为测试方法传递参数值,并且,它是真正意义上的参数构造器,可以传入多组测试数据对测试方法进行测试。被@DataProvider
注解的方法,方法返回值必须为Object[][]
或者Iterator<Object[]>
。
两者的区别是:Iterator 会延迟初始化,当参数数据源很大时,非常有用
例子如下所示:
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class AnnotationDataProviderTest {
@DataProvider(name="testMethodDataProvider")
public Object[][] testMethodDataProvider() {
return new Object[][]{{"value1-1", "value2-1"}, {"value1-2", "value2-2"}, {"value1-3", "value2-3"}};
}
@Test(dataProvider="testMethodDataProvider")
public void test(String arg1, String arg2) {
System.out.println("use @DataProvider to fill method argument : arg1 = " + arg1 + " , arg2 = " + arg2);
}
}
5. @Factory 注解
在一个方法上面打上@Factory注解,表示该方法将返回能够被TestNG测试的测试类。利用了设计模式中的工厂模式。( 主要设置针对测试单元的多次测试而言)例子如下所示:
import org.testng.annotations.Factory;
public class AnnotationFactoryTest {
@Factory
public Object[] getSimpleTest() {
return new Object[]{ new SimpleTest("one"), new SimpleTest("two")};
}
}
import org.testng.annotations.Test;
public class SimpleTest {
private String param;
public SimpleTest(String param) {
this.param = param;
}
@Test
public void test() {
System.out.println("SimpleTest.param = " + param);
}
}
testng.xml配置
<test name="testFactory">
<classes>
<class name="com.testngdemo.AnnotationFactoryTest" />
</classes>
</test>
运行结果:
SimpleTest.param = one
SimpleTest.param = two
6. @Listeners 注解
注意本注解必须定义在类、接口或者枚举类级别。TestNG丰富的 Listener 满足不同阶段的监听。通过 Listener 可以在suite级别、test级别和test method一些执行点执行一些自定义操作,如截图、打印日志等等。常用 Listener 包括
- IAnnotationTransformer
- IAnnotationTransformer2
- IHookable
- IInvokedMethodListener
- IMethodInterceptor
- IReporter 当整个测试运行完毕之后才会通知。IReporter 接受一个对象列表,这些对象描述整个测试运行的情况
- ISuiteListener
- ITestListener 在测试开始、通过、失败等时刻实时通知
三 . 调用 TestNG
可通过如下几种方式调用 TestNG:
- 使用 testng.xml 文件
- ant
- maven,如 mvn clean test -U -Dxml=xmlFileName
- 命令行
参考资料
https://testng.org/doc/index.htmlhttps://testng.org/doc/documentation-main.html
【Quality】 Quality is the value to someone who matters。做测试,首先要找到这个someone是谁,以及这个 someone重视的 value是什么。