TestNG
介绍
TestNG
是一个开源自动化测试框架;TestNG
表示下一代(Next Generation的首字母)。
TestNG的特点:
- 注解
- 使用Java和面向对象的功能
- 灵活的运行时配置
- 支持依赖测试方法,并行测试,负载测试,局部故障
- 灵活的插件API
- 支持多线程测试
TestNG
测试类配置注释说明
注解 | 描述 |
---|---|
@BeforeMethod | 在每个测试方法 前 执行 |
@AfterMethod | 在每个测试方法 后 执行 |
@BeforeClass | 被注释的方法将在当前类的第一个测试方法调用前运行 |
@AfterClass | 被注释的方法将在当前类的所有测试方法调用后运行 |
@BeforeGroups | 被配置的方法将在列表中的gourp前运行。这个方法保证在第一个属于这些组的测试方法调用前立即执行 |
@BeforeTest | 被注释的方法将在测试运行前运行 |
@AfterTest | 被注释的方法将在测试运行后运行 |
@BeforeSuite | 被注释的方法将在所有测试运行前运行 |
@AfterSuite | 被注释的方法将在所有测试运行后运行 |
alwaysRun | 对于每个bufore方法(beforeSuite, beforeTest, beforeTestClass 和 beforeTestMethod, 但是不包括 beforeGroups):\n如果设置为true,被配置的方法将总是运行而不管它属于哪个组。\n对于after方法(afterSuite, afterClass, …): 如果设置为true,被配置的方法甚至在一个或多个先调用的方法失败或被忽略时也将运行。 |
dependsOnGroups | 这个方法依赖的组列表 |
dependsOnMethods | 这个方法依赖的方法列表 |
enabled | 这个类的方法是否激活 |
groups | 这个类或方法所属的分组列表 |
inheritGroups | 如果设置为true,这个方法被属于在类级别被@Test annotation指定的组 |
testng.xml
配置详解
XML
规则
- suite
- –tests
- —-parameters
- —-groups
- ——definitions
- ——runs
- —-classes
- –parameters
XML
简单的大概结构
1 | <suite name="xxx"> |
各个参数说明
<suite>
说明:一个xml
文件只能有一个<suite>
,是一个xml
文件的根级<suite>
由<test>
和<parameters>
组成参数说明:
参数 |说明|使用方法|参数值
——————————|—|—|—name
|必选项,junit
|是否执行Junit模式(识别setup()等)|junit=”true”|true和false,默认falseverbose
|控制台输出的详细内容等级,0-10级(0无,10最详细)|verbose=”5”|0到10parallel
|是否在不同的线程并行进行测试,要与thread-count配套使用|parallel=”mehods”|详见表格下内容,默认falseparent-module
|和Guice框架有关,只运行一次,创建一个parent injector给所有guice injectors|guice-stage
|和Guice框架有关|guice-stage=”DEVELOPMENT”|DEVELOPMENT,PRODUCTION,TOOL,默认”DEVELOPMENT”configfailurepolicy
|测试失败后是再次执行还是跳过,值skip和continue|configfailurepolicy=”skip”|skip、continue,默认skipthread-count
|与parallel配套使用,线程池的大小,决定并行线程数量|thread-count=”10”|整数,默认5annotations
|获取注解,值为javadoc时,使用JavaDoc的注释;否则用JDK5注释|annotations=”javadoc”|javadoctime-out
|设置parallel时,终止执行单元之前的等待时间(毫秒)|time-out=”10000”|整数,单位毫秒skipfailedinvocationcounts
|是否跳过失败的调用|skipfailedinvocationcounts=”true”|true和false,默认falsedata-provider-thread-count
|并发时data-provider的线程池数量|data-provider-thread-count=”5”|整数object-factory
|一个实现IObjectFactory接口的类,实例化测试对象|object-factory=”classname”|类名allow-return-values
|是否允许返回函数值|all-return-values=”true”|true和falsepreserve-order
|是否按照排序执行|preserve-order=”true”|true和false,默认truegroup-by-instances
|按照实例分组|group-by-instances=”true”|true和false,默认false
<test>
说明:一个下可以有多个 ,可以通过 的parallel=”tests”来进行并行测试,必须和thread-count配套使用,否则是无效参数 <test>
由<parameters>
、<groups>
、<classes>
三部分组成参数说明:
参数 |说明|使用方法|参数值
——————————|—|—|—name
|test的名字,将出现在报告里|name=”testname”|test的名字junit
|是否按照Junit模式运行|junit=”true”|true和false,默认falseverbose
|控制台输出的详细内容等级,0-10级(0无,10最详细),不在报告显示|verbose=”5”|0到10parallel
|是否在不同的线程并行进行测试,要与thread-count配套使用|parallel=”mehods”|与suite的parallel一致,默认falsethread-count
|与parallel配套使用,线程池的大小,决定并行线程数量|thread-count=”10”|整数,默认5annotations
|获取注解,值为javadoc时,使用JavaDoc的注释;否则用JDK5注释|annotations=”javadoc”|javadoctime-out
|设置parallel时,终止执行单元之前的等待时间(毫秒)|time-out=”10000”|整数,单位毫秒enabled
|标记是否执行这个test|enabled=”true”|true和false,默认trueskipfailedinvocationcounts
|是否跳过失败的调用|skipfailedinvocationcounts=”true”|true和false,默认falsepreserve-order
|是否按照排序执行,如果是true,将按照xml文件中的顺序去执行|preserve-order=”true”|true和false,默认trueallow-return-values
|是否允许返回函数值|all-return-values=”true”|true和false,默认false
parallel
该参数的值可以是false
、methods
、tests
、classes
、instances
。默认false
parallel
必须和thread-count
配套使用,否则相当于无效参数,thread-count
决定了并行测试时开启的线程数量parallel="mehods"
TestNG将并行执行所有的测试方法在不同的线程里parallel="tests"
TestNG将并行执行在同一个下的所有方法在不同线程里 parallel="classes"
TestNG将并行执行在相同下的方法在不同线程里 parallel="instances"
TestNG将并行执行相同实例下的所有方法在不同的线程里
<parameter>
说明:提供测试数据,有name
和value
两个参数
声明方法:<parameter name = "parameter_name" value = "parameter_value "/>
testng.xml
文件中的<parameter>
可以声明在<suite>
或者<test>
级别,在<test>
下的<parameter>
会覆盖在<suite>
下声明的同名变量
使用示例:1
2
3
4
5
6
7
8
9
10
11
12
13public class TestParameterXML {
"parameter_name1", "parameter_name2" }) ({
public void createConnection(String parameter_name1, int parameter_name2) {
System.out.println("parameter_name1 : " + dbconfig);
System.out.println("parameter_name2 : " + poolsize);
Properties prop = new Properties();
InputStream input = null;
}
}<DataProvider>
使用示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19package com.yiibai;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class TestParameterDataProvider {
"provideNumbers") (dataProvider =
public void test(int number, int expected) {
Assert.assertEquals(number + 10, expected);
}
"provideNumbers") (name =
public Object[][] provideData() {
return new Object[][] { { 10, 20 }, { 100, 110 }, { 200, 210 } };
}
}<groups>
说明:要运行的组,可以自定义一个组,可以包括要执行的,还排除要执行的方法。必须和<classes>
配套使用,从下面的类中找到对应名字的方法<groups>
由<difine>
和<run>
、<dependencies>
三部分组成。<diffine>
可以将group
组成一个新组,包括要执行和不执行的大组;<run>
要执行的方法;<dependencies>
指定了某group
需要依赖的group
(比如下面的例子,group1
需要依赖group2
和group3
先执行)。声明方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14<groups>
<define name ="all">
<include name ="testgroup1"/>
<exclude name ="testgroup2'/>
</define>
<run>
<include name ="all"/>
<include name ="testmethod1"/>
<exclude name="testmethod2"/>
</run>
<dependencies>
<group name ="group1" depends-on="goup2 group3"/>
</dependencies>
</groups><classes>
说明:方法选择器,要执行的方法写在这里,参数有name
和priority
。
注释:
1.下必须写要执行的 ,否则不会执行任何内容,如果填写了class没有写methods,会按照填写的class的下的注释@Test去执行所有的方法
2.下的 如果填写了 ,那只会执行所填写的方法,没有填写的方法不会去执行 声明方法:
1
2
3
4
5
6
7<classes>
<class name="要执行的class名">
<methods>
<include name ="要执行的方法名"/>
</methods>
</class>
</classes><packages>
说明:<packages>
指定包名代替类名。查找包下的所有包含testNG annotation
的类进行测试声明方法:
1
2
3
4
5
6
7<packages>
<package name="packagename"/>
<package name="packagename">
<include name="methodname"/>
<exclude name="methodname"/>
</package>
</packages><listener>
说明:指定listeners
,这个class
必须继承自org.testng.ITestNGListener
。在java
中使用@Listeners({com.example.MyListener.class,com.example.MyMethodInterceptor.class})
的注释也可以有同样效果声明方法:
1
2
3
4<listeners>
<listener class-name="com.example.MyListener"/>
<listener class-name="com.example.MyMehodIntercepor"/>
</listeners>
忽略测试
在测试用例写好,但是并没有调试或者说还没有测试通过时,希望先不要执行该测试,可以使用@Test(enabled = false)
来忽略这个测试方法。默认情况下,enabled
参数是true
。
超时测试
超时
表示如果单元测试花费的时间超过指定的毫秒数,那么TestNG
将会终止它,并标记为失败。超时
也可用于性能测试,以确保方法在合理的时间内返回。
示例代码如下:
1 | package com.yiibai; |
设置失败用例重跑
对于TestNG
,首先重写接口IRetryAnalyzer
,重写该接口中的retry
方法,自定义需要重试的次数maxRetryCount
,如果一个用例失败,自动进入retry
方法,在此方法中判断已经重试的次数是否小于maxRetryCount
,如果是,则返回true
,则自动再次执行失败的用例,如果是失败的用例再次执行还是失败,那么还是自动调用retry
方法,直到到重试次数大于设定的maxRetryCount
了,则返回false
,那么系统就是判定该方法失败了。
失败用例重跑方法代码:
1 | package com.shadow.qa.common.listeners; |
重写了TestNG
的IRetryAnalyzer
接口,那么就需要让系统调用我们重写的接口,需要让TestNG
调用,还需要对TestNG.xml
中的注解接口进行重写。先判断TestNG.xml
中是否有重试分析器,如果没有,则调用我们自己重写类。
失败重跑监听器代码:
1 | package com.shadow.qa.common.listeners; |
使用方法一:在TestNG
的执行文件中配置
在TestNG
的执行文件的suite
标签中,增加一个监听器,用于监听suite
下所有的用例执行情况。
1 | <suite name="接口测试" verbose="1" > |
使用方法二:对特定的用例进行设置
在用例的@Test
中,增加失败用例重跑的参数
1 | "data", description = "Test", retryAnalyzer = TestNGRetryAnalyzer.class) (dataProvider = |
问题处理
使用groups
时,@BeforeClass
、@BeforeSuite
被跳过
有两种解决方式:
在
@BeforeClass
中添加alwaysRun=true
1
2
3
4
5
6
7public class classTest {
true) (alwaysRun=
public void initTest() {};
"testGroup"}) (groups = {
public static void testMethod() {};
}testNG
文件中包含了该class
中存在的groups
时,该class
中的@BeforeClass
才会执行,所以不必担心在所有的@BeforeClass
中都添加alwaysRun=true
会造成没必要的@BeforeClass
执行的问题。在
@BeforeClass
中也添加需要的groups
参数1
2
3
4
5
6
7public class classTest {
"testGroup"}) (groups = {
public void initTest() {};
"testGroup"}) (groups = {
public static void testMethod() {};
}
执行某个包下所有包含某个分组的用例
testNG的xml配置文件如下:
1 |
|
多数文档说groups
必须和classes
配合使用,但是class
是无法用通配符的,会造成要枚举所有的class
,这样就会非常麻烦;
实际上groups
也可以和packages
配合使用,packages
可以使用通配符,这样就大大省去了去找所有有需要的groups
的class
的麻烦