TestNG官方文档记录+例子运行
testng.xml
使用maven工程时,我们可以在工程中添加testng.xml来运行。运行xml,可以使用IDE工具(eclipse、Intellij's IDEA),命令行,ant。使用eclipse需要安装插件,使用IDEA时,直接右键运行
image.png
使用命令行(需要把TestNG加入到class path中)具体命令查看help
java org.testng.TestNG testng1.xml [testng2.xml testng3.xml ...]
testng.xml是依赖testng-1.0.dtd,所以在xml的开头需要把dtd文件加进去,把依赖加进去以后在写xml文件时,IDE才会调起方法
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
例子
使用class名配置运行
--只有一个test
--有多个test
image.png使用package名配置运行
image.png使用group名配置运行,xml文件中不仅要加上group注解,也需要加上classes,group是在classes的范围内挑选所需要的group
修改下代码
public class Demo1 {
@Test(groups = "g1")
public void test1(){
System.out.println("测试01");
}
@Test(groups = "g2")
public void test11(){
System.out.println("测试11");
}
}
public class Demo3 {
@Test(groups = "g1")
public void test3(){
System.out.println("测试03");
}
@Test(groups = "g2")
public void test33(){
System.out.println("测试33");
}
}
image.png
下面是大头了
group
TestNG允许使用group进行分组,一个test不仅属于一个group,可以属于多个group:@Test(groups={"g1","g2"}),在testng.xml中可以配置不同group运行,group可以放在<suite>下,也可以放在<test>下,作用范围的差别:如果<suite>指明g1,<test>指明g2,则g1、g2都会运行的,可以使用include(包含)也可以使用exclude(排除)
下面的例子是运行group名为g1和g2
public class Demo1 {
@Test(groups = {"g1","g2"})
public void test1(){
System.out.println("测试01");
}
@Test(groups = "g2")
public void test11(){
System.out.println("测试11");
}
@Test
public void test111(){
System.out.println("测试111");
}
}
public class Demo3 {
@Test(groups = "g1")
public void test3(){
System.out.println("测试03");
}
@Test(groups = "g2")
public void test33(){
System.out.println("测试33");
}
}
image.png
group名可以使用.,同时在指定要运行哪些group时,也可以使用通配符 星号 (使用通配符 星号,一定要加上. dot star)
public class Demo1 {
@Test(groups = {"windows.g1","linux.g2"})
public void test1(){
System.out.println("测试01");
}
@Test(groups = "linux.g2")
public void test11(){
System.out.println("测试11");
}
@Test
public void test111(){
System.out.println("测试111");
}
}
public class Demo3 {
@Test(groups = "windows.g1")
public void test3(){
System.out.println("测试03");
}
@Test(groups = "linux.g2")
public void test33(){
System.out.println("测试33");
}
}
image.png
当有些test case不运行了以后,我们可以在group中多加一个标签,然后在testng.xml的group中排除该标签,这些case就不会跑起来了。如果有的case没有加上group注解,是不会被运行起来的
public class Demo1 {
@Test(groups = {"checkintest","broken"})
public void test1(){
System.out.println("测试01");
}
@Test(groups = "checkintest")
public void test11(){
System.out.println("测试11");
}
@Test
public void test111(){
System.out.println("测试111");
}
}
image.png
dependencies
有时候有些case是需要依赖其他case的,这个时候就可以用dependencies注解
默认情况下,被依赖的类需要运行成功,依赖的类才会运行,而且被依赖的类一定会在依赖类之前运行
如下图,test22运行在test2之前
dependsOnMethods
image.png
如果怕失败了,依赖类不运行,可以多加个alwaysRun=true,无论如何都要运行的,被依赖类如果失败了,依赖类是不运行(skipped)而不是失败
image.png image.pngdependsOnGroups
image.png
在testng.xml中也可以使用dependsOnGroup。目前实践结果是,只能放在<test>下,放在<suite>会报错:org.testng.TestNGException: java.lang.NullPointerException。而且
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="suite01" verbose="1">
<test name="test">
<groups>
<dependencies>
<group name="ss" depends-on="yy"></group>
</dependencies>
</groups>
<classes>
<class name="com.tyoko.demo.TestNGDemo1"></class>
</classes>
</test>
</suite>
运行结果是被依赖的方法先运行,然后按照书写顺序运行,最后是依赖的类
image.png并发
parallel="methods",运行所有方法在各自的线程,依赖方法也是运行在不同的线程,但是如果你有指定的话会按照你指定的执行
parallel=”tests",将相同<test>中的case运行在同一个线程,不同的<test>分开不同线程运行。如果在同个<test>中有非线程安全的类的话,可以使用group以保证在同个线程内运行所有case
parallel=“classes",同个类中的方法运行在同个线程中,不同类的方法运行在不同线程中
parallel="instances",同个实例的方法运行在同个线程,不同实例则运行在不同线程中
image.png
参数化
parameters
在方法上使用Parameters({""})注解,在testng.xml中添加<parameter name="" value=""/>
name必须一致,方法则会去读取xml文件中设置的值。一般用于配置数据库信息时使用。在<suite><test>中都可以设置,有作用域差别
@Parameters({ "first-name" })
@Test
public void testSingleString(String firstName) {
System.out.println("Invoked testString " + firstName);
assert "Cedric".equals(firstName);
}
<suite name="My suite">
<parameter name="first-name" value="Cedric"/>
<test name="Simple example">
<-- ... -->
dataProviders
返回值是Object[][],二维数组,设置了name后,方法上的注解dataProvider="name"使用name,如果未设置name,可以使用方法名。
@DataProvider(name = "test1")
public Object[][] createData1() {
return new Object[][] {
{ "Cedric", new Integer(36) },
{ "Anne", new Integer(37)},
};
}
//This test method declares that its data should be supplied by the Data Provider
//named "test1"
@Test(dataProvider = "test1")
public void verifyData1(String n1, Integer n2) {
System.out.println(n1 + " " + n2);
}
实际使用时,可以把数据写在同一个类中(静态方法),再去获取数据
public class BaseFactory {
@DataProvider(name = "getData")
public static Object[][] createData(){
return new Object[][]{
{"wanger",18},
{"lisi",16}
};
}
}
image.png
一堆的before、after,可以添加以下注解:alwaysRun(不可以使用在beforeGroup) dependsOnGroups dependsOnMethods enables groups inheritGroups(=true,该方法属于指定的group,注解在class级别)
@BeforeSuite
@AfterSuite
@BeforeTest
@AfterTest
@BeforeGroups
@AfterGroups
@BeforeClass
@AfterClass
@BeforeMethod
@AfterMethod
实践结果是@BeforeMethod@AfterMethod@BeforeClass@AfterClass可以写在同一个类中。@BeforeTest@AfterTest另起一个类,不然在多个类中都写了@BeforeTest@AfterTest会同时运行多个,造成结果失败
@BeforeGroups@AfterGroups一定要加上是在哪写group中使用的
public class GroupFactory {
@BeforeGroups(groups = {"yy"})
public void beforeGroup(){
System.out.println("Before group");
}
@AfterGroups(groups = {"yy"})
public void afterGroup(){
System.out.println("After group");
}
}
image.png
@BeforeSuite@AfterSuite就直接新起一个类来写要操作的方法
public class SuiteFactory {
@BeforeSuite
public void beforeSuite(){
System.out.println("Before Suite");
}
@AfterSuite
public void afterSuite(){
System.out.println("After Suite");
}
}
image.png