1 - Introduction
-
编写测试的业务逻辑并在代码中插入TestNG注释。
-
在 testng.xml 或 build.xml 文件中添加有关测试的信息(例如类名,希望运行的组,等)。
-
- Run TestNG。
-
一个 XML 文件表示一个套件。它可以包含一个或多个测试,并由<suite>标签定义。
-
一个<test>标签表示一个测试,它可以包含一个或多个TestNG类。
-
TestNG类是至少包含一个TestNG注释的Java类。它由<class>标签表示,可以包含一个或多个测试方法。
-
测试方法是在源代码中由@Test注解的Java方法。
-
所有注释的列表和简要解释。这将使您对TestNG提供的各种功能有一个了解,但您可能希望参考专门讨论这些注释的一节来了解详细信息。
-
testng.xml文件的描述、语法以及可以在其中指定的内容。
-
各种特性的详细列表以及如何结合注释和 testng.xml 使用它们。
2 - Annotations
|
@BeforeSuite
@AfterSuite
@BeforeTest
@AfterTest
@BeforeGroups
@AfterGroups
@BeforeClass
@AfterClass
@BeforeMethod
@AfterMethod
|
TestNG类的配置信息
:
@BeforeSuite: 该注解标记的方法将在<suite>标签中所有的测试方法执行之前执行。
@AfterSuite: 该注解标记的方法将在<suilte>标签中所有的测试方法执行之后执行。
@BeforeTest: 该注解标记的方法将在<test>标签中所有的测试方法执行之前执行。
@AfterTest: 该注解标记的方法将在<test>标签中所有的测试方法执行之后执行。
@BeforeGroups: 该注解标记的方法将在组列表运行之前运行。这个方法保证在调用属于任何这些组的第一个测试方法之前运行。
@AfterGroups: 该注解标记的方法将在组列表运行之后运行。该方法保证在调用属于任何这些组的最后一个测试方法zhi'hou运行。
@BeforeClass: 该注解标记的方法将在调用该类的第一个测试方法之前执行。
@AfterClass: 该注解标记的方法将在该类所有的测试方法运行之后执行。
@BeforeMethod: 该注解标记的方法将在每一个测试方法执行之前运行。
@AfterMethod: 该注解标记的方法将在每一个测试方法执行之后执行。
在TestNG类的超类中注释的行为
当这些注解在 TestNG 超类上使用时,也一并会被子类继承下来。因此,在一个公共超类中集中多个测试方法的设置是很有用的。
在这种情况下,TestNG保证“@Before”方法按继承顺序执行(首先执行最高的超类,然后沿着继承链向下执行),“@After”方法按相反的顺序执行(沿着继承链向上执行)。
| |
|
alwaysRun
|
对于before方法(beforeSuite, beforeTest, beforeTestClass和beforeTestMethod,但不包括beforeGroups):如果设置为true,这个配置方法将运行,无论它属于哪个组。
对于after方法(afterSuite, afterClass,…):如果设置为true,即使之前调用的一个或多个方法失败或被跳过,这个配置方法也会运行。
| |
|
dependsOnGroups
|
此方法所依赖的组列表。
| |
|
dependsOnMethods
|
此方法所依赖的方法列表
| |
|
enabled
|
是否启用该类/方法上的方法
| |
|
groups
|
该类/方法所属的组列表
| |
|
inheritGroups
|
如果为true,此方法将属于@Test注释中在类级别指定的组。
| |
|
onlyForGroups
|
只适用于@BeforeMethod和@AfterMethod。如果指定,则只有当对应的测试方法属于列出的组之一时,才会调用此setup/teardown方法。
| |
|
@DataProvider
|
将方法标记成为测试方法提供数据的方法。带有该注解的方法,必须返回一个 Object[][],其中每个 Object[] 都可以成为对接测试方法的参数列表。要使用该 DataProvider 返回的参数列表的测试方法,其@Test注解中 dataProvider 参数值要传入该方法的方法名或@DataProvider注解的name参数值。(带有该注解的方法,必须是静态方法)
| |
|
name
|
当前DataProvier方法的名称。如果不传入时,默认使用该方法的methodName。
| |
|
parallel
|
如果设置为true,则使用该方法提供数据的测试方法,将并行(多线程)执行。默认值为false。
| |
|
@Factory
|
将方法标记为给 TestNG 提供Test类的工厂。该方法必须返回一个Object[]。(返回的Object 会直接被当作测试类,去执行对应的测试方法。创建测试类时,可以批量传参,给测试方法使用。 )
| |
|
@Listeners
|
在测试类上,定义监听器。(指定当前类使用的监听器)
| |
|
value
|
一个继承了 org.testng.ITestNGListener 的类的数组。
| |
|
@Test
|
将类或方法标记为测试的一部分。
| |
|
alwaysRun
|
如果设置为true,在依赖的测试方法执行失败后,此测试方法也会执行。
| |
|
dataProvider
|
指定为改方法提供数据的dataProvider的name。
| |
|
dataProviderClass
|
dataProvider 方法所在类的类路径(test执行时会在此类中查找 dataProvider 指定的方法)。如果没有指定,将在当前测试方法所在类或其基类之一上查找dataProvider指定的方法。如果指定了类路径,则dataProvider指定的方法需要是 static 的。
| |
|
dependsOnGroups
|
此测试方法依赖的组列表。
| |
|
dependsOnMethods
|
此测试方法依赖的方法列表。
| |
|
description
|
测试方法的描述。
| |
|
enabled
|
是否启用该类/方法上的方法。
( enabled=false时,会将方法禁用,即直接跳过)
| |
|
expectedExceptions
|
该测试方法预期抛出的异常列表。如果 没有抛出异常 或 抛出的异常与列表中的异常不同,则此测试将被标记为失败。
| |
|
groups
|
当前测试类/方法所属的组列表。
| |
|
invocationCount
|
当前测试方法执行的次数。
| |
|
invocationTimeOut
|
此测试方法在所有每次调用的累计时间中所花费的最大毫秒数。如果未指定invocationCount,则将忽略此属性。(每次调用时的,最大调用时长。)
| |
|
priority
|
此测试方法的优先级。序号小的优先执行。
| |
|
successPercentage
|
此测试方法预期执行成功的百分比。
| |
|
singleThreaded
|
如果设置为true,这个测试类上的所有方法都保证在同一个线程中运行,即使测试当前正在使用parallel="methods"运行。这个属性只能在类级别使用,如果在方法级别使用,它将被忽略。注意:此属性过去被称为sequential(现在已弃用)。
| |
|
timeOut
|
此测试应该执行的最大毫秒数。(超时后会报失败)
| |
|
threadPoolSize
|
此测试方法的线程池的大小。该测试方法将由invocationCount指定的多个线程调用。
注意:如果未指定invocationCount,此属性将被忽略
| |
3 - testng.xml
-
使用 testng.xml 调用
-
使用 ant
-
通过 command 命令行调用
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1" >
<test name="Nopackage" >
<classes>
<class name="NoPackageTest" />
</classes>
</test>
<test name="Regression1">
<classes>
<class name="test.sample.ParameterSample"/>
<class name="test.sample.ParameterTest"/>
</classes>
</test>
</suite>
你可以指定包名,而不是类名:
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1" >
<test name="Regression1" >
<packages>
<package name="test.sample" />
</packages>
</test>
</suite>
在这个例子中,TestNG 将查看 test.sample 包中所有的类,并只保留具有TestNG注解的类。
<test name="Regression1">
<groups>
<run>
<exclude name="brokenTests" />
<include name="checkinTests" />
</run>
</groups>
<classes>
<class name="test.IndividualMethodsTest">
<methods>
<include name="testMethod" />
</methods>
</class>
</classes>
</test>
您还可以在testng.xml中定义新的组,并在属性中指定额外的细节,例如是否并行运行测试,使用多少线程,是否运行JUnit测试,等等。
<test name="Regression1" preserve-order="false">
<classes>
<class name="test.Test1">
<methods>
<include name="m1" />
<include name="m2" />
</methods>
</class>
<class name="test.Test2" />
</classes>
</test>
请参阅DTD以获得特性的完整列表,或者继续阅读。
4 - Running TestNG
-
Command line
java org.testng.TestNG testng1.xml [testng2.xml testng3.xml ...]
您需要指定至少一个XML文件来描述您试图运行的TestNG套件。另外,以下命令行开关是可用的:
| Option |
Argument
| Documentation |
|
-configfailurepolicy
|
skip | continue
|
如果@Before*方法失败,TestNG应该继续执行套件中剩余的测试还是跳过它们。默认行为是跳过。
|
|
-d
|
一个目录
|
生成报告的目录(默认为test-output)。
|
|
-dataproviderthreadcount
|
并行运行测试时用于 data providers 的默认线程数。
|
这将设置并行运行测试时 data providers 使用的默认最大线程数。它只有在选择了并行模式时才会生效(例如,使用-parallel选项)。这可以在套件定义中重写。
|
|
-excludegroups
|
以逗号分隔的组列表。
|
要从本次运行中排除的组列表。
|
|
-groups
|
以逗号分隔的组列表。
|
要运行的组列表(例如:"windows,linux,regression").
|
|
-listener
|
可以在类路径中找到以逗号分隔的Java类列表。
|
你自己指定的监听器。这些类要实现
org.testng.ITestListener
|
|
-usedefaultlisteners
|
true|false
|
是否使用默认监听器
|
|
-methods
|
以逗号分隔的完全限定类名和方法列表。例如com.example.Foo.f1,com.example.Bar.f2
|
允许你指定要运行的单个方法。
|
|
-methodselectors
|
用逗号分隔的Java类和定义方法选择器的方法的优先级列表。
|
允许您在命令行上指定方法选择器。例如:com.example.Selector1:3,com.example.Selector2:2
|
|
-parallel
|
methods|tests|classes
|
如果指定,将设置用于确定运行测试时如何使用并行线程的默认机制。如果没有设置,默认机制是根本不使用并行线程。这可以在套件定义中重写。
|
|
-reporter
|
自定义报告监听器的扩展配置(继承了 report listener)
|
类似于-listener,不同之处在于它允许在报告实例上配置 javabeans-style 的属性。
例如: -reporter com.test.MyReporter:methodFilter=*insert*,enableFiltering=true
这个选项可以配置多次,每个需要生成的报告都可以配置一次。
|
|
-sourcedir
|
以逗号分隔的目录列表。
|
javadoc注释的测试源所在的目录。只有在使用javadoc类型注释时才需要此选项。(例如 "src/test" or "src/test/org/testng/eclipse-plugin;src/test/org/testng/testng").
|
|
-suitename
|
测试套的默认名称
|
这指定了在命令行上定义的测试套件的套件名称。如果suite.xml文件或源代码指定了不同的套件名称,则忽略此选项。如果您使用双引号“like this”将它括起来,则可以创建包含空格的套件名称。
|
|
-testclass
|
可以在类路径中找到的以逗号分隔的类列表。
|
用逗号分隔的类文件列表 (e.g. "org.foo.Test1,org.foo.test2").
|
|
-testjar
|
一个 jar
|
指定包含测试类的jar文件。如果在这个jar文件的根目录下找到一个testng.xml文件,就会使用它,否则,在这个jar文件中找到的所有测试类都将被认为是测试类。
|
|
-testname
|
测试的默认名称
|
这指定了在命令行上定义的测试的名称。如果suite.xml文件或源代码指定了不同的测试名称,则忽略此选项。如果您使用双引号“like this”将其包围起来,则可以创建一个包含空格的测试名称。
|
|
-testnames
|
用逗号分隔测试名称列表。
|
只有在<test>标签中定义的匹配这些名称之一的测试将被运行。
|
|
-testrunfactory
|
可以在类路径中找到的Java类。
|
允许你指定自己的测试运行程序。这个类需要实现
org.testng.ITestRunnerFactory.
|
|
-threadcount
|
并行运行测试时使用的默认线程数。
|
This sets the default maximum number of threads to use for running tests in parallel. It will only take effect if the parallel mode has been selected (for example, with the -parallel option). This can be overridden in the suite definition.
|
|
-xmlpathinjar
|
jar文件中XML文件的路径。
|
这个属性应该包含测试jar中一个有效XML文件的路径(例如:“resources/ testng.xml”)。默认是“testng.xml”,这意味需要在jar文件的根目录下有一个名为“testng.xml”的文件。该option 只有在指定了 -testjar 时,才会生效
|
C:> more c:\command.txt
-d test-output testng.xml
C:> java org.testng.TestNG @c:\command.txt
另外,可以在Java虚拟机的命令行上传递TestNG属性
java -Dtestng.test.classpath="c:/build;c:/java/classes;" org.testng.TestNG testng.xml
以下是TestNG能够理解的属性:
| Property | Type |
Documentation
|
|
testng.test.classpath
|
以分号分隔的包含测试类的一系列目录。
|
如果设置了这个属性,TestNG将使用它来查找测试类,而不是类路径。如果您在XML文件中使用package标记,并且在类路径中有很多类,其中大多数不是测试类,那么这样做很方便。
|
java org.testng.TestNG -groups windows,linux -testclass org.test.MyTest
ant任务和TestNG.xml允许您使用更多参数启动TestNG(要包含的方法、指定参数等),因此只有当您试图了解TestNG并希望快速启动和运行时,才应该考虑使用命令行。
5 - Test methods,Test classes and Test groups
5.1 - Test methods
<suite allow-return-values="true">
or
<test allow-return-values="true">
5.2 - Test Groups
-
Check-in 测试。在提交新代码之前,应该运行这些测试。它们通常应该是快速的,并确保没有基本的功能被破坏。
-
功能测试。这些测试应该涵盖软件的所有功能,并且至少每天运行一次,尽管理想情况下您希望连续运行它们。
public class Test1 {
@Test(groups = { "functest", "checkintest" })
public void testMethod1() {
}
@Test(groups = {"functest", "checkintest"} )
public void testMethod2() {
}
@Test(groups = { "functest" })
public void testMethod3() {
}
}
用以下调用TestNG
<test name="Test1">
<groups>
<run>
<include name="functest"/>
</run>
</groups>
<classes>
<class name="example1.Test1"/>
</classes>
</test>
将运行该类中的所有测试方法,而使用 checktest 调用它将只运行testMethod1()和testMethod2()。
@Test
public class Test1 {
@Test(groups = { "windows.checkintest" })
public void testWindowsOnly() {
}
@Test(groups = {"linux.checkintest"} )
public void testLinuxOnly() {
}
@Test(groups = { "windows.functest" )
public void testWindowsToo() {
}
}
<test name="Test1">
<groups>
<run>
<include name="windows.*"/>
</run>
</groups>
<classes>
<class name="example1.Test1"/>
</classes>
</test>
注意:TestNG使用 regular expressions, 而不是 wildmats。 注意区别 (例如, "任何字符" 使用 ".*"匹配,-- 点 星 -- 而不是 "*")。
Method groups
<test name="Test1">
<classes>
<class name="example1.Test1">
<methods>
<include name=".*enabledTestMethod.*"/>
<exclude name=".*brokenTestMethod.*"/>
</methods>
</class>
</classes>
</test>
在不需要重新编译任何东西的情况下,禁用单个方法非常方便,但我不建议过多地使用这种技术,因为如果开始重构Java代码,它可能会破坏测试框架(在标记中使用的正则表达式可能不再与方法匹配)。
5.3 - Groups of groups
<test name="Regression1">
<groups>
<define name="functest">
<include name="windows"/>
<include name="linux"/>
</define>
<!-- 官网上应该是漏掉了下面这部分 -->
<define name="checkintest">
<include name="windows"/>
</define>
<define name="all">
<include name="functest"/>
<include name="checkintest"/>
</define>
<run>
<include name="all"/>
</run>
</groups>
<classes>
<class name="test.sample.Test1"/>
</classes>
</test>
5.4 - Exclusion groups
@Test(groups = {"checkintest", "broken"} )
public void testMethod2() {
}
<test name="Simple example">
<groups>
<run>
<include name="checkintest"/>
<exclude name="broken"/>
</run>
</groups>
<classes>
<class name="example1.Test1"/>
</classes>
</test>
通过这种方式,我将得到一个干净的测试运行,同时跟踪哪些测试被破坏了,需要稍后修复。
5.5 - Parial groups
@Test(groups = { "checkin-test" })
public class All {
@Test(groups = { "func-test" )
public void method1() { ... }
public void method2() { ... }
}
在这个类中,method2()是在类级别定义的“check -test”组的一部分,而method1()同时属于“check -test”和“func-test”两个组。
5.6 - Parameters
5.6.1 - Parameters from testng.xml
@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">
<-- ... -->
同样的技术也可以用于@Before/After和@Factory注释:
@Parameters({ "datasource", "jdbcDriver" })
@BeforeMethod
public void beforeTest(String ds, String driver) {
m_dataSource = ...; // look up the value of datasource
m_jdbcDriver = driver;
}
@Parameters("db")
@Test
public void testNonExistentParameter(@Optional("mysql") String db) { ... }
-
任何已经有@Test,@Before/After或@Factory注释的方法。
-
最多一个构造函数的测试类。在这种情况下,当需要实例化测试类时,TestNG将使用 Testng.xml 中指定的值初始化参数去调用这个特定的构造函数。这个特性可以用来将类中的字段初始化为测试方法要使用的值。
-
XML参数按照在注释中找到它们的顺序映射到Java参数,如果数字不匹配,TestNG将发出错误。
-
参数是有作用范围的。在 testng.xml 中,您可以在<suite>标签下声明它们,也可以在<test>标签下声明它们。如果两个参数具有相同的名称,则 <test> 标签中定义的参数具有优先级。如果您需要指定一个适用于所有测试的参数,这是很方便的。
5.6.2 - Paramters with DataProviders
//This method will provide data to any test method that declares that its Data Provider
//is named "test1"
@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);
}
//将打印
Cedric 36
Anne 37
public class StaticProvider {
@DataProvider(name = "create")
public static Object[][] createData() {
return new Object[][] {
new Object[] { new Integer(42) }
};
}
}
public class MyTest {
@Test(dataProvider = "create", dataProviderClass = StaticProvider.class)
public void test(Integer n) {
// ...
}
}
Data provider 也支持注入。TestNG将使用测试上下文进行注入。Data Provider 的方法可以返回以下类型之一:
-
一个Object对象的二维数组(Object[][]),其中第一个维度的大小是调用测试方法的次数,第二个维度的大小包含一个必须与测试方法的参数类型兼容的对象数组。这就是上面的例子所说明的情况。
-
一个 Iterator<Object[]>。与Object[][]唯一的区别是Iterator允许您惰性地创建测试数据。TestNG将调用迭代器,然后调用带有该迭代器返回的参数的测试方法。如果您有很多参数集要传递给方法,而您不想在前面创建所有参数,那么这尤其有用。(dataProvider 需要是一个手写的迭代器)
-
一个Object对象的一位数组(Object[])。
这类似于Iterator<Object[]>,但会导致对源数组的每个元素调用一次测试方法。(Object[] 中每一个元素调用一次测试方法。) -
Iterator<Object>。Object[]的惰性替代。导致对迭代器的每个元素调用一次测试方法。(Iterator中没有给元素调用一次测试方法。)
-
@DataProvider(name = "test1")
public Iterator<Object[]> createData() {
return new MyIterator(DATA);
}
使用MyCustomData[]作为返回类型
@DataProvider(name = "test1")
public MyCustomData[] createData() {
return new MyCustomData[]{ new MyCustomData() };
}
或者它的惰性选项 Iterator<MyCustomData>
@DataProvider(name = "test1")
public Iterator<MyCustomData> createData() {
return Arrays.asList(new MyCustomData()).iterator();
}
Iterator的形参类型(Stream)不能显式参数化
@DataProvider(name = "test1")
public Iterator<Stream> createData() {
return Arrays.asList(Stream.of("a", "b", "c")).iterator();
}
如果你在声明@DataProvider 以 java.lang.reflect.Method作为第一个参数,TestNG将传入测试方法作为 @DataProvider 方法的第一个参数的入参。当几个测试方法使用相同的@DataProvider,并且您希望它根据为哪个测试方法提供数据而返回不同的值时,这一点特别有用。
@DataProvider(name = "dp")
public Object[][] createData(Method m) {
System.out.println(m.getName()); // print test method name ps:TestNG会将下一步要调用的测试方法,传入当前的方法中,因此你可以根据不同的方法名称判断, 来返回不同的dataProvider。
return new Object[][] { new Object[] { "Cedric" }};
}
@Test(dataProvider = "dp")
public void test1(String s) {
}
@Test(dataProvider = "dp")
public void test2(String s) {
}
因此将显示:
@DataProvider(parallel = true)
// ...
从XML文件运行的并行数据提供程序(parallel data providers)共享相同的线程池,默认情况下线程池大小为10。你可以在XML文件的标签中修改这个值:
<suite name="Suite1" data-provider-thread-count="20" >
...
如果希望在不同的线程池中运行几个特定的数据提供程序,则需要从不同的XML文件运行它们。
5.6.3 - Patamters in reports
5.7 - Dependencies
-
在运行更多的测试方法之前,确保一定数量的测试方法已经完成并成功。
-
初始化你的测试,同时希望这个初始化方法也成为测试方法(带有@Before/After标记的方法将不会成为最终报告的一部分)。
5.7.1 - Dependencies with annotations
-
Hard dependencies(艰难的依赖关系)。你(的测试方法a)所依赖的所有方法必须已经运行并成功运行。如果你的依赖项中至少发生了一个故障,则不会在报告中调用你(的测试方法a)并将其标记为 SKIP。
-
Soft dependencies(柔软的依赖关系)。你(的测试方法a)将始终在依赖的测试方法执行之后执行,即使其中一些依赖的测试方法已经执行失败。当你只想确保您的测试方法以特定的顺序运行,但它们的成功并不真正依赖于其他方法的成功时,这是很有用的。软依赖是通过在@Test注解中添加“alwaysRun=true”获得的。
@Test
public void serverStartedOk() {}
@Test(dependsOnMethods = { "serverStartedOk" })
public void method1() {}
在这个例子中,method1()被声明为依赖于方法serverStartedOk(),这保证了serverStartedOk()总是首先被调用。
@Test(groups = { "init" })
public void serverStartedOk() {}
@Test(groups = { "init" })
public void initEnvironment() {}
@Test(dependsOnGroups = { "init.*" })
public void method1() {}
在这个例子中,method1()声明为依赖于任何匹配正则表达式“init.*”的组,这保证了方法serverStartedOk()和initEnvironment()总是在method1()之前被调用。
a(1)
a(2)
b(2) // 这里应该是 b(1) ,前提是方法a和b共用同一个dataProvider,并且 dataProvider 返回的参数是 [[1],[2]],此时由于b依赖于a,所以会先将a执行两次,然后再将b执行两次
b(2)
TestNG将不会运行b(),直到所有实例都调用了它们的a()方法。
signIn("us")
signOut("us")
signIn("uk")
signOut("uk")
对于这种排序,可以使XML配置文件的 group-by-instances。该属性在<suite>或<test>上有效:(个人理解,此处的 instance 因该是 dataProvider 中的对象实例,修改此配置后,关联同一个dataProvider 的测试会先使用同一个参数依次调用,然后继续使用下一次参数依次调用所有方法)
<suite name="Factory" group-by-instances="true">
or
<test name="Factory" group-by-instances="true">
5.7.2 - Dependencies in XML
<test name="My suite">
<groups>
<dependencies>
<group name="c" depends-on="a b" />
<group name="z" depends-on="c" />
</dependencies>
</groups>
</test>
<depends-on>属性包含一个空格分隔的组列表。
5.8 -Fatories
public class TestWebServer {
@Test(parameters = { "number-of-times" })
public void accessPage(int numberOfTimes) {
while (numberOfTimes-- > 0) {
// access the web page
}
}
}
<test name="T1">
<parameter name="number-of-times" value="10"/>
<classes>
<class name= "TestWebServer" />
</classes>
</test>
<test name="T2">
<parameter name="number-of-times" value="20"/>
<classes>
<class name= "TestWebServer"/>
</classes>
</test>
<test name="T3">
<parameter name="number-of-times" value="30"/>
<classes>
<class name= "TestWebServer"/>
</classes>
</test>
这很快就会变得无法管理,所以,你应该使用工厂:
public class WebTestFactory {
@Factory
public Object[] createInstances() {
Object[] result = new Object[10];
for (int i = 0; i < 10; i++) {
result[i] = new WebTest(i * 10);
}
return result;
}
}
新的测试类现在是:
public class WebTest {
private int m_numberOfTimes;
public WebTest(int numberOfTimes) {
m_numberOfTimes = numberOfTimes;
}
@Test
public void testServer() {
for (int i = 0; i < m_numberOfTimes; i++) {
// access the web page
}
}
}
你的testng.xml只需要引用包含工厂方法的类,因为测试实例本身将在运行时创建:
<class name="WebTestFactory" />
或者,如果以编程方式构建测试套件实例,可以使用与测试相同的方式添加工厂:
TestNG testNG = new TestNG();
testNG.setTestClasses(WebTestFactory.class);
testNG.run();
@Factory(dataProvider = "dp")
public FactoryDataProviderSampleTest(int n) {
super(n);
}
@DataProvider
static public Object[][] dp() {
return new Object[][] {
new Object[] { 41 },
new Object[] { 42 },
};
}
这个示例将让TestNG创建两个测试类,其中构造函数的值为41,另一个为42。
5.9 - Class level annotations
@Test
public class Test1 {
public void test1() {
}
public void test2() {
}
}
类级@Test注释的作用是使该类的所有公共方法成为测试方法,即使它们没有注释。如果您想添加某些属性,您仍然可以在方法上重复@Test注释。
@Test
public class Test1 {
public void test1() {
}
@Test(groups = "g1")
public void test2() {
}
}
将生成test1()和test2()测试方法,但最重要的是,test2()现在属于组“g1”。
5.10 - Ignoring tests
-
在一个类中(或)
-
在一个特定的包中(或)
-
在一个包及其所有子包中
import org.testng.annotations.Ignore;
import org.testng.annotations.Test;
@Ignore
public class TestcaseSample {
@Test
public void testMethod1() {
}
@Test
public void testMethod2() {
}
}
@Ignore 注释比单独的 @Test 方法注释具有更高的优先级。当在类上放置 @Ignore 时,该类中的所有测试将被禁用。
5.11 - Parallelism and time-outs
5.11.1 - Parallel suites
5.11.2 - Parallel tests,classes and methods
-
parallel="methods":TestNG将在单独的线程中运行所有测试方法。依赖的方法也会在单独的线程中运行,但它们会按照您指定的顺序运行。
-
parallel="tests": TestNG将在同一个线程中运行同一个<test>标签中的所有方法,但每个<test>标签将在一个单独的线程中。这允许您将所有线程不安全的类分组在同一个<test>中,并保证它们都运行在同一个线程中,同时利用TestNG使用尽可能多的线程运行测试。
-
parallel="classes": TestNG将在同一个线程中运行同一个类中的所有方法,但每个类将在单独的线程中运行。
-
parallel="instances": TestNG将在同一个线程中运行同一个实例中的所有方法,但两个不同实例中的两个方法将在不同的线程中运行。
5.12 - Rerunning failed test
-
构建 org.testng.IRetryAnalyzer 接口的实现类
-
将该实现类绑定到@Test注解,例如@Test(retryAnalyzer = localtry .class)
5.13 - JUnit tests
-
JUnit 3:
-
类中所有以test*开头的方法都将被运行
-
如果测试类上有一个setUp()方法,它将在每个测试方法之前被调用
-
如果测试类上有一个方法tearDown(),它将在每个测试方法之后被调用
-
如果测试类包含方法suite(),那么将调用此方法返回的所有测试
-
-
JUnit 4:
-
TestNG将使用 org.junit.runner.JUnitCore 运行器来运行你的测试
-
5.14 - Running TestNG programmatically
5.15 - BeanShell and advanced group selection
-
它必须返回一个布尔值。除了这个约束之外,任何有效的BeanShell代码都是允许的(例如,您可能希望在工作日返回true,在周末返回false,这将允许您根据日期以不同的方式运行测试)。
-
为了方便起见,TestNG定义了以下变量:
-
java.lang.reflect.Method method:当前的测试方法。
-
org.testng.ITestNGMethod testngMethod:当前测试方法描述。
-
java.util.Map<String,String> groups:当前测试方法所属组的映射。
-
-
您可能希望用CDATA声明包围表达式(如上所示),以避免对保留的XML字符进行冗长的引用。
5.16 - Annotation Transformers
5.17 - Method Interceptors
-
方法按顺序运行。这些是所有具有依赖项或依赖项的测试方法。这些方法将按特定的顺序运行。
-
方法没有特定的运行顺序。这些方法都不属于第一类。这些测试方法的运行顺序是随机的,每次运行的顺序都可能不同(尽管在默认情况下,TestNG将尝试按类对测试方法进行分组)。
-
与您在参数中收到的列表相同,但顺序不同。
-
更小的一个 IMethodInstance 对象列表。
-
更大的一个 IMethodInstance 对象列表。
5.18 - TestNG Listeners
-
在命令行中使用 -listener ( Using -listener on the command line)。
-
在 ant 中使用 <listeners>( Using <listeners> with ant)。
-
在 testng.xml 文件中使用 <listeners> 。
-
在任何测试类上使用 @Listeners 注解。
-
使用 ServiceLoader。
5.18.1 - Specifying listeners with testng.xml or in Java
-
首先定义一个新的自定义注解,用于指定此限制:
5.18.2 - Specifying listeners with ServiceLoader
5.19 - Dependency injection
5.19.1 - Native dependency injection
-
任何@Before方法或@Test方法都可以声明 ITestContext 类型的参数。
-
任何@AfterMethod方法都可以声明一个类型为 ITestResult 的参数,它将反映刚刚运行的测试方法的结果。
-
任何@Before和@After方法(@BeforeSuite和@AfterSuite除外)都可以声明一个 XmlTest 类型的参数,该参数包含当前的 <test> 标签。
-
任何@BeforeMethod(和@AfterMethod)都可以声明 java.lang.reflect.Method 类型的参数。这个参数将接收测试方法,这个测试方法将在 @BeforeMethod 完成后被调用(或者在@AfterMethod运行后)。
-
任何@BeforeMethod都可以声明Object[]类型的参数。该参数将接收将要提供给即调用的的测试方法的参数列表,这些参数可以由TestNG注入,比如java.lang.reflect.Method,也可以来自@DataProvider。
-
任何@DataProvider都可以声明ITestContext或java.lang.reflect.Method类型的参数。后一个参数将接收将要调用的测试方法。
|
Annotation
|
ITestContext
|
XmlTest
|
Method
|
Object[]
|
ITestResult
|
|
BeforeSuite
|
Yes
|
No
|
No
|
No
|
No
|
|
BeforeTest
|
Yes
|
Yes
|
No
|
No
|
No
|
|
BeforeGroups
|
Yes
|
Yes
|
No
|
No
|
No
|
|
BeforeClass
|
Yes
|
Yes
|
No
|
No
|
No
|
|
BeforeMethod
|
Yes
|
Yes
|
Yes
|
Yes
|
Yes
|
|
Test
|
Yes
|
No
|
No
|
No
|
No
|
|
DataProvider
|
Yes
|
No
|
Yes
|
No
|
No
|
|
AfterMethod
|
Yes
|
Yes
|
Yes
|
Yes
|
Yes
|
|
AfterClass
|
Yes
|
Yes
|
No
|
No
|
No
|
|
AfterGroups
|
Yes
|
Yes
|
No
|
No
|
No
|
|
AfterTest
|
Yes
|
Yes
|
No
|
No
|
No
|
|
AfterSuite
|
Yes
|
No
|
No
|
No
|
No
|
5.19.2 - Guice dependency injection
5.20 - Listening to method invocations
5.21 - Overriding test methods
5.22 - Altering suites (or) tests
-
通过套件 xml文件中的<listenters>标签。
6 - Test results
6.1 - Success, failure and assert
6.2 - Logging and results
-
Listeners 实现了 org.testng.ITestListener 接口,并实时通知测试何时开始、通过、失败等等……
-
Reporters 实现了 org.testng.IReporter 接口,并在TestNG运行所有套件时收到通知。IReporter实例接收描述整个测试运行的对象列表。
6.2.1— Logging Listeners
6.2.2 - Logging Reporters
6.2.3 - JUnitReports
6.2.4 - Reporter API
Reporter.log ( "M3 WAS CALLED" ) ;
6.2.5 - XML Reports
-
: -将报告名称与其属性分开
-
= -用于分隔属性的键/值对
-
, -用于分隔多个键/值对
|
Property
|
Comment
|
Default value
|
|
outputDirectory
|
一个字符串,指示输出XML文件的目录
| TestNG的输出目录 |
|
timestampFormat
|
指定报告生成的日期字段的格式
|
yyyy-MM-dd'T'HH:mm:ss'Z'
|
|
fileFragmentationLevel
|
一个值为1、2或3的整数,表示XML文件生成的方式:
1 - 将在一个文件中生成所有结果。
2 - 每个套件在一个单独的XML文件中生成,该文件链接到主文件。
3 -和2一样,加上从套件文件中引用的独立的测试用例文件。
|
1
|
|
splitClassAndPackageNames
|
这个布尔值指定为<class>元素生成类名的方式。例如,你将得到<class class="com.test.MyTest"> 为 false 而 <class class="MyTest" package="com.test"> 为 true 。
|
false
|
|
generateGroupsAttribute
|
一个布尔值,指示是否应该为 <test-method> 元素生成groups属性。该特性旨在提供一种简单的方法来检索包含测试方法的组,而不必遍历 <group> 元素。
|
false
|
|
generateTestResultAttributes
|
一个指定是否为每个 <test-method>元素生成 <attributes> 标签的布尔值,它包括测试结果的属性(关于测试结果属性,请参考 ITestResult.setAttribute())。每个属性 toString() 的结果都将被写入<attribute name="[attribute name]"> 标签。
|
false
|
|
stackTraceOutputMethod
|
针对异常生成的堆栈跟踪类型,取值如下:
0 -没有stacktrace(只是异常类和消息)。
1 -堆栈跟踪的一个简短版本,只距顶部几行
2 -包含所有内部异常的完整堆栈跟踪
3 -短和长堆栈跟踪
|
2
|
|
generateDependsOnMethods
|
使用这个属性来启用/禁用<test-method>元素的depends-on-methods 属性的生效。
|
true
|
|
generateDependsOnGroups
|
使用这个属性来启用/禁用<test-method>元素的depends-on-groups 属性的生效。
|
true
|
6.2.6 - TestNG Exit Codes
|
FailedWithinSuccess
|
Skipped
|
Failed
|
Status Code
|
Remarks
|
|
No
|
No
|
No
|
0
|
Passed tests
|
|
No
|
No
|
Yes
|
1
|
Failed tests
|
|
No
|
Yes
|
No
|
2
|
Skipped tests
|
|
No
|
Yes
|
Yes
|
3
|
Skipped/Failed tests
|
|
Yes
|
No
|
No
|
4
|
FailedWithinSuccess tests(失败后又成功的测试?)
|
|
Yes
|
No
|
Yes
|
5
|
FailedWithinSuccess/Failed tests
|
|
Yes
|
Yes
|
No
|
6
|
FailedWithinSuccess/Skipped tests
|
|
Yes
|
Yes
|
Yes
|
7
|
FailedWithinSuccess/Skipped/Failed tests
|
7 - YAML
8 - Dry Run for your tests(调试运行)
9 - JVM Arguments in TestNG
|
JVM Argument
|
Comment
|
Default value
|
|
testng.thread.affinity
|
A Boolean indicating whether TestNG should resort to running dependent methods on the same thread as the upstream methods.
一个布尔值,指示TestNG是否应该在与上游方法相同的线程上运行依赖的方法。
|
false
|
|
testng.mode.dryrun
|
A Boolean indicating whether TestNG should simulate a real execution. In this mode the test methods are not actually executed.
一个布尔值,指示TestNG是否应该模拟真实的执行。在这种模式下,测试方法实际上不会被执行。
|
false
|
|
testng.test.classpath
|
A String that represents a list of zip files or jars that need to be added to the TestNG classpath for it to retrieve test classes for execution.
一个字符串,表示需要添加到TestNG类路径的zip文件或jar文件列表,以便它检索测试类执行。
|
""
|
|
skip.caller.clsLoader
|
A Boolean indicating whether TestNG should skip using the current ClassLoader for loading classes.
一个布尔值,指示TestNG是否应该使用当前的ClassLoader来加载类。
|
false
|
|
testng.dtd.http
|
A Boolean indicating whether TestNG should load DTDs from http endpoints.
一个布尔值,指示TestNG是否应该从http端点加载dtd。
|
false
|
|
testng.show.stack.frames
|
A Boolean indicating whether TestNG should show detailed stack traces in reports.
一个布尔值,指示TestNG是否应该在报告中显示详细的堆栈跟踪。
|
false
|
|
testng.memory.friendly
|
A Boolean indicating whether TestNG should be memory cognizant and use light weight test method representations.
一个布尔值,指示TestNG是否应该是内存认知的,并使用轻量级测试方法表示。
|
false
|
|
testng.strict.parallel
|
A Boolean indicating that TestNG should attempt to start all test methods simultaneously when there are more than one test tags and parallelism has been set to methods.
一个布尔值,表示当有多个测试标签且已设置为并行执行测试方法时,TestNG是否应该尝试同时启动所有测试方法。
|
false
|
|
emailable.report2.name
|
A String indicating the file name into which the emailable reports are to be written into.
一个字符串,指示要生成的可发送报告的文件名。
|
emailable-report.html
|
|
oldTestngEmailableReporter
|
A Boolean indicating whether TestNG should use the old emailable report listener for building simple html emailable report.
一个布尔值,指示TestNG是否应该使用旧的emailable报告监听器来构建简单的可发送的html报告。
|
false
|
|
noEmailableReporter
|
A Boolean indicating whether TestNG should use the NEW emailable report listener for building simple html emailable report.
一个布尔值,指示TestNG是否应该使用新的emailable报告监听器来构建简单的可发送的html报告。
|
true
|
|
testng.report.xml.name
|
A String indicating the file name into which the xml reports are to be written into.
一个字符串,执行xml报告的文件名。
|
testng-results.xml
|
|
fileStringBuffer
|
A Boolean indicating whether TestNG should output verbose logs when working with very large text data.
个布尔值,指示在处理非常大的文本数据时,TestNG是否应该输出详细日志。
|
false
|
|
stacktrace.success.output.level
|
A String indicating the log levels to be included in the XML Reports (Valid values include : NONE (no stacktraces), SHORT (short stacktrace), FULL (full stacktrace), BOTH (both short and full stacktrace).
表示XML报告中包含的日志级别的字符串(有效值包括:NONE(无stacktrace), SHORT(短stacktrace), FULL(全stacktrace), BOTH(均短)。
|
FULL
|
-
EJBGen:EJB标签生成器。
-
TestNG:使用注释、测试组和方法参数的测试框架。
-
Doclipse:一个JavaDoc标签Eclipse插件。
-
J15:一个Eclipse插件,可以帮助您将代码迁移到新的JDK 1.5构造中。
-
SGen:用一个简单的插件架构替代XDoclet。
-
Canvas:一个基于Groovy语言的模板生成器。
本文档详尽地介绍了TestNG的使用,包括测试方法、注解、testng.xml配置、依赖管理和并行运行测试等方面。它涵盖了从基础概念到高级特性的全部内容,旨在帮助开发者深入理解和应用TestNG进行单元测试。
1094

被折叠的 条评论
为什么被折叠?



