最全的TestNG官方文档中文翻译

本文档详尽地介绍了TestNG的使用,包括测试方法、注解、testng.xml配置、依赖管理和并行运行测试等方面。它涵盖了从基础概念到高级特性的全部内容,旨在帮助开发者深入理解和应用TestNG进行单元测试。
部署运行你感兴趣的模型镜像

1 - Introduction

TestNG是一个旨在简化广泛的测试需求测试框架,从单元测试(单独测试一个类)到集成测试(测试由几个类、几个包甚至几个外部框架(如应用服务器)组成的整个系统)。
编写测试通常由三个步骤组成:
  • 编写测试的业务逻辑并在代码中插入TestNG注释。
  • 在 testng.xml  或 build.xml 文件中添加有关测试的信息(例如类名,希望运行的组,等)。
  • - Run TestNG。
你可以在欢迎页面上找到一个快速示例。
本文档中使用的概念如下:
  • 一个 XML 文件表示一个套件。它可以包含一个或多个测试,并由<suite>标签定义。
  • 一个<test>标签表示一个测试,它可以包含一个或多个TestNG类。
  • TestNG类是至少包含一个TestNG注释的Java类。它由<class>标签表示,可以包含一个或多个测试方法。
  • 测试方法是在源代码中由@Test注解的Java方法。
TestNG测试可以通过@beforexxx和@afterxxx注释进行配置,这些注释允许在某个点(点可以是上面列出的任何一项)之前和之后执行一些Java逻辑。
本手册的其余部分将解释如下:
  • 所有注释的列表和简要解释。这将使您对TestNG提供的各种功能有一个了解,但您可能希望参考专门讨论这些注释的一节来了解详细信息。
  • testng.xml文件的描述、语法以及可以在其中指定的内容。
  • 各种特性的详细列表以及如何结合注释和 testng.xml 使用它们。

2 - Annotations

下面是 TestNG 中可用的注释及其属性的快速概述。
@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:
  • 使用 testng.xml 调用
  • 使用 ant
  • 通过 command 命令行调用
本节描述 testng.xml 的格式(您将在下面找到关于ant和命令行的文档)。
可以在主网站: testng-1.0.dtd 上找到 testng.xml 的当前DTD。(为了方便起见,您可能更喜欢浏览HTML版本)。
下面是一个示例 testng.xml 文件:
<!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测试,等等。

默认情况下,TestNG将按照在XML文件中找到测试的顺序运行测试。如果希望此文件中列出的类和方法以不可预测的顺序运行,请将 preserve-order 属性设置为false
<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

可以通过不同的方式调用TestNG:
本节仅说明如何从命令行调用TestNG。如果您对其他方式感兴趣,请按上述其中一个链接。
假设在类路径中有TestNG,调用TestNG的最简单方法如下:
java org.testng.TestNG testng1.xml [testng2.xml testng3.xml ...]

您需要指定至少一个XML文件来描述您试图运行的TestNG套件。另外,以下命令行开关是可用的:

Command Line Parameters
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 时,才会生效
可以通过不带任何参数调用TestNG来获得该文档。
您还可以将命令行开关放在一个文本文件中,例如输入c:\command.txt,并告诉TestNG使用该文件来检索它的参数(将TestNG的命令行参数放入到txt文件中,然后用testNG检索txt文件):
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能够理解的属性:

System properties
PropertyType
Documentation
testng.test.classpath
以分号分隔的包含测试类的一系列目录。
如果设置了这个属性,TestNG将使用它来查找测试类,而不是类路径。如果您在XML文件中使用package标记,并且在类路径中有很多类,其中大多数不是测试类,那么这样做很方便。
例如:
java org.testng.TestNG -groups windows,linux -testclass org.test.MyTest

ant任务和TestNG.xml允许您使用更多参数启动TestNG(要包含的方法、指定参数等),因此只有当您试图了解TestNG并希望快速启动和运行时,才应该考虑使用命令行。

重要提示:如果您还指定了testng.xml文件,则指定应该运行哪些测试的命令行标志将被忽略,但-includedgroups和-excludedgroups除外,它们将覆盖testng.xml中发现的所有组包含/排除。

5 - Test methods,Test classes and Test groups

5.1 - Test methods

用 @Test 注解的方法。被 @Test 注解的方法的返回值会被忽略,除非你在 testng.xml 文件中将 allow-return-values 设置为 true 。
<suite allow-return-values="true">
or
<test allow-return-values="true">

5.2 - Test Groups

TestNG允许您执行复杂的测试方法分组。你不仅可以声明方法属于组,还可以指定包含其他组的组。然后可以调用TestNG,并要求它包含一组特定的组(或正则表达式),同时排除另一组。这为您在如何划分测试方面提供了最大的灵活性,并且如果您想要连续运行两组不同的测试,则不需要重新编译任何内容。
测试组在 testng.xml 文件中指定,可以在 <test> 或 <suite> 标签下找到。在<suite> 标签中指定的组,应用于其 <suite>标签下的所有的 <test> 标签。注意,组在这些标签中是累积的:如果在 <suite> 中指定组“a”,在 <test> 中指定组“b”,那么“a”和“b”都将被包含。
例如,有至少两类测试是很常见的
  • Check-in 测试。在提交新代码之前,应该运行这些测试。它们通常应该是快速的,并确保没有基本的功能被破坏。
  • 功能测试。这些测试应该涵盖软件的所有功能,并且至少每天运行一次,尽管理想情况下您希望连续运行它们。
通常,Check-in 测试是功能测试的一个子集。TestNG允许您以一种非常直观的方式指定测试组。例如,你可以这样构造你的测试:你的整个测试类属于“functest”组,另外一些方法属于“checkintest”组:
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()。

下面是另一个例子,这次使用了正则表达式。假设你的一些测试方法不应该在Linux上运行,你的测试应该是这样的:
@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() {
 }
}
你可以使用下面的testng.xml只启动Windows方法:
<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

组还可以包括其他组。这些组被称为“元组”。例如,您可能想要定义一个组“all”,这个组包括“checkintest”组和“functest”组。“functest”组本身又将包含组“windows”和“linux”,而“checkintest”组又将只包含“windows”。下面是你将如何在你的配置文件中定义它:
<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

TestNG允许包含或排除组。
例如,测试由于最近的更改而暂时中断,而您还没有时间修复中断,这是非常常见的。4 然而,你确实希望有清晰的功能测试运行,所以你需要停用这些测试(被中断的测试),但记住它们需要重新激活。
解决这个问题的一个简单方法是创建一个名为“broken”的组,并使这些测试方法(被中断的测试)属于它(名为“broken”的组)。例如,在上面的例子中(5.2 的例子),我知道testMethod2()现在被破坏了,所以我想禁用它:
@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>

通过这种方式,我将得到一个干净的测试运行,同时跟踪哪些测试被破坏了,需要稍后修复。

注意:您也可以通过使用@Test和@Before/After注释上可用的“enabled”属性来禁用单个测试。

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

测试方法不必是无参数的。您可以在每个测试方法上使用任意数量的参数,并指示TestNG通过@Parameters注解传递正确的参数。
有两种方式设置这些参数:使用 testng.xml 或 通过编程方式。

5.6.1 - Parameters from testng.xml

如果你使用简单的参数值,你可以在你的testng.xml中指定它们:
@Parameters({ "first-name" })
@Test
public void testSingleString(String firstName) {
 System.out.println("Invoked testString " + firstName);
 assert "Cedric".equals(firstName);
}
在这段代码中,我们指定Java方法的 firstName 参数应该接收名为 first-name 的 XML参数 的值。这个 XML参数 在testng.xml中定义:
<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;
}
这一次,两个Java参数 ds 和 driver 将分别接收配置文件给出的 datasource 和 jdbc-driver 的值。
参数可以通过@Optional 注解声明为可选:
@Parameters("db")
@Test
public void testNonExistentParameter(@Optional("mysql") String db) { ... }
如果在testng.xml文件中没有找到名为“db”的参数,你的测试方法将收到在 @Optional 注解中指定的默认值:“mysql”。
@Parameters 注解可以放在以下位置:
  • 任何已经有@Test,@Before/After或@Factory注释的方法。
  • 最多一个构造函数的测试类。在这种情况下,当需要实例化测试类时,TestNG将使用 Testng.xml 中指定的值初始化参数去调用这个特定的构造函数。这个特性可以用来将类中的字段初始化为测试方法要使用的值。
        
    注意:
  • XML参数按照在注释中找到它们的顺序映射到Java参数,如果数字不匹配,TestNG将发出错误。
  • 参数是有作用范围的。在 testng.xml 中,您可以在<suite>标签下声明它们,也可以在<test>标签下声明它们。如果两个参数具有相同的名称,则 <test> 标签中定义的参数具有优先级。如果您需要指定一个适用于所有测试的参数,这是很方便的。

5.6.2 - Paramters with DataProviders

如果您需要传递复杂的参数,或者需要从Java中创建的参数(复杂对象、从属性文件或数据库中读取的对象等等),在testng.xml中指定参数可能是不够的。在这种情况下,您可以使用Data Provider来提供需要测试的值。Data Provider是类上的一个方法,它返回对象的数组的数组。这个方法用@DataProvider注解:
//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
@Test方法用 dataProvider 属性指定它的 Data Provider。该属性的名称必须与同一个类上用 @DataProvider(name="…") 注解的一个方法的 name 的传值一致。
默认情况下,将在当前测试类或其基类之一中查找 Data Provider。如果你想把你的数据提供程序放在一个不同的类中,它需要是一个静态方法或一个带有非参数构造函数的类,并且你需要在 dataProviderClass 属性中指定可以找到它的类:
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中没有给元素调用一次测试方法。)
必须指出,返回类型不仅限于Object,MyCustomData[][] 或 Iterator< Supplier> 也是可能的。唯一的限制是,对于迭代器,它的形参类型本身不能显式参数化。下面是这个特性的一个例子:
@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中打印测试方法的名称:
@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) {
}

因此将显示:

test1
test2
Data providers可以设置parallel属性并行运行:
@DataProvider(parallel = true)
// ...

从XML文件运行的并行数据提供程序(parallel data providers)共享相同的线程池,默认情况下线程池大小为10。你可以在XML文件的标签中修改这个值:

<suite name="Suite1" data-provider-thread-count="20" >
...

如果希望在不同的线程池中运行几个特定的数据提供程序,则需要从不同的XML文件运行它们。

5.6.3 - Patamters in reports

用于调用测试方法的参数会显示在TestNG生成的HTML报告中。下面是一个例子:
                                                                                                   

5.7 - Dependencies

有时,你需要以特定的顺序调用测试方法。以下是一些例子:
  • 在运行更多的测试方法之前,确保一定数量的测试方法已经完成并成功。
  • 初始化你的测试,同时希望这个初始化方法也成为测试方法(带有@Before/After标记的方法将不会成为最终报告的一部分)。
TestNG允许使用注释或XML指定依赖关系。

5.7.1 - Dependencies with annotations

你可以使用 @Test 注解的 dependsOnMethods 或 dependsOnGroups 属性。
他们有两种依赖关系:
  • 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()之前被调用。

    注意:如前所述,在不同的测试运行中,不保证属于同一组的方法的调用顺序相同。
如果一个被它(例如:test method a)依赖的方法失败了,并且你对它(test method a)有一个硬依赖(alwaysRun=false,这是默认值),那么它(test method a)不会被标记为FAIL,而是被标记为SKIP。被跳过的方法(test method a)将被展示在最终的报告中(在HTML中既不是红色也不是绿色),这是很重要的,因为被跳过的方法不一定是失败的。
dependsOnGroups和dependsOnMethods都接受正则表达式作为参数。对于dependsOnMethods,如果你依赖的方法恰好有几个重载版本,那么所有的重载方法都会被调用。如果您只想调用其中一个重载方法,则应该使用dependsOnGroups。
有关依赖方法的更高级示例,请参考本文( this article   ~ 官方文档上此链接已不可用了),本文使用继承为多个依赖关系的问题提供了一个优雅的解决方案。
默认情况下,依赖方法按类分组。例如,如果方法b()依赖于方法a(),并且您有多个包含这些方法的类实例(因为数据提供程序的工厂),那么调用顺序将如下:
a(1)
a(2)
b(2)   // 这里应该是 b(1) ,前提是方法a和b共用同一个dataProvider,并且 dataProvider 返回的参数是 [[1],[2]],此时由于b依赖于a,所以会先将a执行两次,然后再将b执行两次
b(2)

TestNG将不会运行b(),直到所有实例都调用了它们的a()方法。

在某些场景中,这种行为可能不可取,例如测试不同国家的web浏览器的登录和退出。在这种情况下,你会想要以下顺序:
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 

你可以在testng.xml文件中指定您的组依赖关系。你可以使用 <dependncies> 标签来实现这一点:
<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

工厂允许您动态地创建测试。例如,假设您想创建一个测试方法,该方法将多次访问Web站点上的一个页面,并且您想用不同的值调用它:(下面是错误实现场景的一个示例)
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();
工厂方法可以接收像 @Test 和 @Before/After 这样的参数,它必须返回 Object[]。返回的对象可以是任何类的(不一定与工厂类相同),它们甚至不需要包含TestNG注释(在这种情况下,它们将被TestNG忽略)。
工厂还可以与数据提供程序一起使用,您可以通过将@Factory注释放在常规方法或构造函数上来利用这一功能。下面是一个构造函数工厂的例子:
@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注解可以放在类上而不仅仅是测试方法上:
@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

TestNG让你忽略所有的@Test的方法:
  • 在一个类中(或)
  • 在一个特定的包中(或)
  • 在一个包及其所有子包中
使用新的注释@Ignore。
当在方法级别使用 @Ignore 注解时,在功能上等同于 @Test(enabled=false) 。下面的示例演示了如何忽略一个类中的所有测试。
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 时,该类中的所有测试将被禁用。

要忽略特定包中的所有测试,只需要创建 package-info.java 并向其添加 @Ignore 注解。这里有一个例子:
@Ignore
package com.testng.master;
import org.testng.annotations.Ignore;
这将导致 com.testng.master 包及其所有子包中的所有 @Test 方法被忽略。

5.11 - Parallelism and time-outs 

您可以指示TestNG以各种方式在不同的线程中运行测试。

5.11.1 - Parallel suites 

如果您正在运行几个套件文件(例如:“java org.testng.TestNG testng1.xml testng2.xml”),你希望这些套件在单独的线程中运行。您可以使用以下命令行标志来指定线程池的大小:
java org.testng.TestNG -suitethreadpoolsize 3 testng1.xml testng2.xml testng3.xml
对应的ant任务名称是 suitethreadpoolsize 。

5.11.2 - Parallel tests,classes and methods

<suite>标签上的 parallel 属性可以取以下值之一:
<suite name="My suite" parallel="methods" thread-count="5">
<suite name="My suite" parallel="tests" thread-count="5">
<suite name="My suite" parallel="classes" thread-count="5">
<suite name="My suite" parallel="instances" thread-count="5">
  • parallel="methods":TestNG将在单独的线程中运行所有测试方法。依赖的方法也会在单独的线程中运行,但它们会按照您指定的顺序运行。
  • parallel="tests": TestNG将在同一个线程中运行同一个<test>标签中的所有方法,但每个<test>标签将在一个单独的线程中。这允许您将所有线程不安全的类分组在同一个<test>中,并保证它们都运行在同一个线程中,同时利用TestNG使用尽可能多的线程运行测试。
  • parallel="classes": TestNG将在同一个线程中运行同一个类中的所有方法,但每个类将在单独的线程中运行。
  • parallel="instances": TestNG将在同一个线程中运行同一个实例中的所有方法,但两个不同实例中的两个方法将在不同的线程中运行。
此外,属性thread-count允许您指定应该为该执行分配多少线程。 (?如果分配的线程数不满足并行执行后要分配的线程数,该怎么办???并行是并行,线程是线程??)
    注意:@Test 的timeOut属性在并行和非并行模式下都可以工作。
您还可以指定从不同的线程调用@Test方法。你可以使用属性threadPoolSize来实现这个结果:
@Test(threadPoolSize = 3, invocationCount = 10,  timeOut = 10000)
public void testServer() {
在这个例子中,函数testServer将从三个不同的线程被调用十次。另外,timeOut=10秒 的超时可以保证这个线程上没有一个线程会永远阻塞。

5.12 - Rerunning failed test

每当套件中的测试失败时,TestNG就会在输出目录中创建一个名为 testng-failed.xml 的文件。这个XML文件包含只运行这些失败的方法所需的信息,允许您快速地重现失败,而不必运行整个测试。因此,典型的会话是这样的:
java -classpath testng.jar;%CLASSPATH% org.testng.TestNG -d test-outputs testng.xml
java -classpath testng.jar;%CLASSPATH% org.testng.TestNG -d test-outputs test-outputs\testng-failed.xml
请注意,testng-failed.xml将包含所有必需的依赖方法,这样就可以保证运行失败的方法而不会出现任何SKIP失败。
有时,您可能希望TestNG在测试失败时自动重试测试。在这些情况下,您可以使用重试分析器。当您将重试分析器绑定到测试时,TestNG自动调用重试分析器,以确定TestNG是否可以再次重试测试用例,以查看刚刚失败的测试现在是否通过。下面是如何使用重试分析器:
  1. 构建 org.testng.IRetryAnalyzer 接口的实现类
  2. 将该实现类绑定到@Test注解,例如@Test(retryAnalyzer = localtry .class)
下面是重试分析器的实现实例,它最多重试测试三次。
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
public class MyRetry implements IRetryAnalyzer {
  private int retryCount = 0;
  private static final int maxRetryCount = 3;
  @Override
  public boolean retry(ITestResult result) {
    if (retryCount < maxRetryCount) {
      retryCount++;
      return true;
    }
    return false;
  }
}
import org.testng.Assert;
import org.testng.annotations.Test;
public class TestclassSample {
  @Test(retryAnalyzer = MyRetry.class)
  public void test2() {
    Assert.fail();
  }
}

5.13 - JUnit tests

TestNG可以运行JUnit 3和JUnit 4测试。您需要做的就是将JUnit jar文件放到类路径中,在 testng.classNames 属性指定你的 JUnit 测试类并且将 testng.junit 属性设置为 true :
<test name="Test1" junit="true">
  <classes>
    <!-- ... -->
在这种情况下,TestNG的行为类似于JUnit,这取决于在类路径上找到的JUnit版本:
  • JUnit 3:
    • 类中所有以test*开头的方法都将被运行
    • 如果测试类上有一个setUp()方法,它将在每个测试方法之前被调用
    • 如果测试类上有一个方法tearDown(),它将在每个测试方法之后被调用
    • 如果测试类包含方法suite(),那么将调用此方法返回的所有测试
  • JUnit 4:
    • TestNG将使用 org.junit.runner.JUnitCore 运行器来运行你的测试

5.14 - Running TestNG programmatically

你可以很容易地从你自己的程序中调用TestNG:
TestListenerAdapter tla = new TestListenerAdapter();
TestNG testng = new TestNG();
testng.setTestClasses(new Class[] { Run2.class });
testng.addListener(tla);
testng.run();
这个例子创建了一个  TestNG 对象,并运行测试类 Run2。它还添加了一个 TestListener。您既可以使用适配器类 org.testng.TestListenerAdapter ,也可以自己实现 org.testng.ITestListener。这个接口包含各种回调方法,让您跟踪测试何时开始,成功,失败,等等…
类似地,您可以在 testng.xml 文件上调用TestNG,也可以自己创建一个虚拟 testng.xml 文件。为了做到这一点,您可以使用  org.testng.xml: XmlClassXmlTest 等包中的类。这些类中的每一个都对应于XML中的一个标记。
例如,假设您想创建以下虚拟文件:
<suite name="TmpSuite" >
  <test name="TmpTest" >
    <classes>
      <class name="test.failures.Child"  />
    <classes>
    </test>
</suite>
你可以使用以下代码:
XmlSuite suite = new XmlSuite();
suite.setName("TmpSuite");
XmlTest test = new XmlTest(suite);
test.setName("TmpTest");
List<XmlClass> classes = new ArrayList<XmlClass>();
classes.add(new XmlClass("test.failures.Child"));
test.setXmlClasses(classes) ;
然后你可以将这个XmlSuite传递给TestNG:
List<XmlSuite> suites = new ArrayList<XmlSuite>();
suites.add(suite);
TestNG tng = new TestNG();
tng.setXmlSuites(suites);
tng.run();
请参阅   JavaDocs 了解整个API。

5.15 - BeanShell and advanced group selection

如果 testng.xml 中的 <include> 和 <exclude> 标签不能满足您的需要,您可以使用  BeanShell 表达式来决定是否应该在测试运行中包含某个测试方法。你可以在 <test> 标签下指定这个表达式:
<test name="BeanShell test">
   <method-selectors>
     <method-selector>
       <script language="beanshell"><![CDATA[
         groups.containsKey("test1")
       ]]></script>
     </method-selector>
   </method-selectors>
  <!-- ... -->
当在 testng.xml 文件中发现 <script> 标签时,TestNG将忽略当前 <test> 标签中组和方法的后续 <include> 和 <exclude> :你的BeanShell表达式将是决定是否包含测试方法的唯一方法。
以下是关于BeanShell脚本的附加信息:
  • 它必须返回一个布尔值。除了这个约束之外,任何有效的BeanShell代码都是允许的(例如,您可能希望在工作日返回true,在周末返回false,这将允许您根据日期以不同的方式运行测试)。
  • 为了方便起见,TestNG定义了以下变量:
    • java.lang.reflect.Method method:当前的测试方法。
    • org.testng.ITestNGMethod testngMethod:当前测试方法描述。
    • java.util.Map<String,String> groups:当前测试方法所属组的映射。
  • 您可能希望用CDATA声明包围表达式(如上所示),以避免对保留的XML字符进行冗长的引用。
注意:
从7.5版本开始,TestNG默认不引入任何对BeanShell实现的依赖。
因此,为了利用基于BeanShell的方法选择器,请记住在BeanShell上添加一个显式依赖。

5.16 - Annotation Transformers

TestNG允许您在运行时修改所有注释的内容。如果源代码中的注释在大多数情况下都是正确的,但也有一些情况需要重写它们的值,那么这种方法就特别有用。
为了实现这一点,您需要使用 Annotation Transformer。
Annotation Transformer是一个实现以下接口的类:
public interface IAnnotationTransformer {
  /**
   * This method will be invoked by TestNG to give you a chance
   * to modify a TestNG annotation read from your test classes.
   * You can change the values you need by calling any of the
   * setters on the ITest interface.
   * TestNG会调用这个方法给你修改冲测试类中读取的TestNG注解的机会。你可以通过调用任意ITest接口的setters来改变其值。
   *
   * Note that only one of the three parameters testClass,
   * testConstructor and testMethod will be non-null.
   * 注意,三个参数testClass、testConstructor和testMethod中只有一个是非空的。
   *
   * @param annotation The annotation that was read from your
   * test class.
   * @param annotation annotation参数将从你的测试类中读取。
   * @param testClass If the annotation was found on a class, this
   * parameter represents this class (null otherwise).
   * 如果注解是在一个类上找到的,那么这个参数表示这个类(否则为空)。
   * @param testConstructor If the annotation was found on a constructor,
   * this parameter represents this constructor (null otherwise).
   * @param testMethod If the annotation was found on a method,
   * this parameter represents this method (null otherwise).
   */
  public void transform(ITest annotation, Class testClass,
      Constructor testConstructor, Method testMethod);
}
像所有其他的TestNG监听器一样,你可以在命令行或用ant指定这个类:
java org.testng.TestNG -listener MyTransformer testng.xml
或通过编程:
TestNG tng = new TestNG();
tng.setAnnotationTransformer(new MyTransformer());
// ...
当调用transform()方法时,可以调用ITest test参数的任何setter,以便在TestNG进一步执行之前更改其值。
例如,下面是覆盖属性invocationCount的方法,但只覆盖其中一个测试类的测试方法invoke():
public class MyTransformer implements IAnnotationTransformer {
  public void transform(ITest annotation, Class testClass,
      Constructor testConstructor, Method testMethod)
  {
    if ("invoke".equals(testMethod.getName())) {
      annotation.setInvocationCount(5);
    }
  }
}
IAnnotationTransformer 只允许您修改@Test注解。如果需要修改其他TestNG注释(配置注解,@Factory或@DataProvider),请使用 IAnnotationTransformer2。

5.17 - Method Interceptors

一旦TestNG计算出测试方法被调用的顺序,这些方法就会被分成两组:
  • 方法按顺序运行。这些是所有具有依赖项或依赖项的测试方法。这些方法将按特定的顺序运行。
  • 方法没有特定的运行顺序。这些方法都不属于第一类。这些测试方法的运行顺序是随机的,每次运行的顺序都可能不同(尽管在默认情况下,TestNG将尝试按类对测试方法进行分组)。
为了让你对属于第二类的方法有更多的控制,TestNG定义了以下接口:
public interface IMethodInterceptor {
  List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context);
}
在参数中传递的方法列表是所有以随机顺序运行的方法。你的拦截方法期望返回一个类似的IMethodInstance列表,它可以是以下任何一个:
  • 与您在参数中收到的列表相同,但顺序不同。
  • 更小的一个 IMethodInstance 对象列表。
  • 更大的一个 IMethodInstance 对象列表。
一旦定义了拦截器,就将其作为监听器传递给TestNG。例如:
java -classpath "testng-jdk15.jar:test/build" org.testng.TestNG -listener test.methodinterceptors.NullMethodInterceptor
   -testclass test.methodinterceptors.FooTest
有关等价的ant语法,请参阅  ant documentation 中的listener属性。
例如,这里有一个方法拦截器,它将重新排序方法,使属于“fast”组的测试方法总是首先运行:
public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
  List<IMethodInstance> result = new ArrayList<IMethodInstance>();
  for (IMethodInstance m : methods) {
    Test test = m.getMethod().getConstructorOrMethod().getAnnotation(Test.class);
    Set<String> groups = new HashSet<String>();
    for (String group : test.groups()) {
      groups.add(group);
    }
    if (groups.contains("fast")) {
      result.add(0, m);
    }
    else {
      result.add(m);
    }
  }
  return result;
}

5.18 - TestNG Listeners

有几个接口允许您修改TestNG的行为。这些接口被广泛称为“TestNG listener”。下面是一些监听器:
当你实现了其中一个接口时,你可以通过以下方式让TestNG知道它:

5.18.1 - Specifying listeners with testng.xml or in Java

下面是在 testng.xml 文件中定义监听器的方法:
<suite>
  <listeners>
    <listener class-name="com.example.MyListener" />
    <listener class-name="com.example.MyMethodInterceptor" />
  </listeners>
...
或者如果你喜欢在Java中定义这些监听器:
@Listeners({ com.example.MyListener.class, com.example.MyMethodInterceptor.class })
public class MyTest {
  // ...
}
@Listeners 注解可以包含除 IAnnotationTransformer 和 IAnnotationTransformer2 之外任何继承了 org.testng.ITestNGListener 的类。原因是需要在过程的早期就知道这些监听器,以便TestNG可以使用它们重写注解,因此需要在TestNG .xml文件中指定这些侦听器。
注意,@Listeners注释将应用于整个套件文件,就像您在testng.xml文件中指定了它一样。如果您想限制它的作用域(例如,只在当前类上运行),侦听器中的代码可以首先检查将要运行的测试方法并决定接下来要做什么。以下是如何做到这一点。
  1. 首先定义一个新的自定义注解,用于指定此限制:
@Retention(RetentionPolicy.RUNTIME)
@Target ({ElementType.TYPE})
public @interface DisableListener {}
        2. 在你常规监听器中添加如下编辑检查:
public void beforeInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) {
  ConstructorOrMethod consOrMethod =iInvokedMethod.getTestMethod().getConstructorOrMethod();
  DisableListener disable = consOrMethod.getMethod().getDeclaringClass().getAnnotation(DisableListener.class);
  if (disable != null) {
    return;
  }
  // else resume your normal operations 否则恢复正常操作
}
        3. 注释掉不调用监听器的测试类:
@DisableListener
@Listeners({ com.example.MyListener.class, com.example.MyMethodInterceptor.class })
public class MyTest {
  // ...
}

5.18.2 - Specifying listeners with ServiceLoader 

最后,JDK提供了一种非常优雅的机制,通过ServiceLoader类在类路径上指定接口实现。
使用ServiceLoader,您所需要做的就是创建一个包含监听器和一些配置文件的jar文件,当您运行TestNG时,将该jar文件放在类路径上,TestNG将自动找到它们。
下面是一个具体的例子。
让我们先创建一个监听器(任何TestNG监听器都可以):
package test.tmp;
public class TmpSuiteListener implements ISuiteListener {
  @Override
  public void onFinish(ISuite suite) {
    System.out.println("Finishing");
  }
  @Override
  public void onStart(ISuite suite) {
    System.out.println("Starting");
  }
}
编译这个文件,然后在META-INF/services/org.testng.ITestNGListener 所在的位置创建一个文件,然后根据你想要实现的接口用 implementation(s) 的格式来命名这个文件。
你最终应该得到以下目录结构,只有两个文件:
$ tree
|____META-INF
| |____services
| | |____org.testng.ITestNGListener
|____test
| |____tmp
| | |____TmpSuiteListener.class
$ cat META-INF/services/org.testng.ITestNGListener
test.tmp.TmpSuiteListener
在这个目录下创建一个jar:
$ jar cvf ../sl.jar .
added manifest
ignoring entry META-INF/
adding: META-INF/services/(in = 0) (out= 0)(stored 0%)
adding: META-INF/services/org.testng.ITestNGListener(in = 26) (out= 28)(deflated -7%)
adding: test/(in = 0) (out= 0)(stored 0%)
adding: test/tmp/(in = 0) (out= 0)(stored 0%)
adding: test/tmp/TmpSuiteListener.class(in = 849) (out= 470)(deflated 44%)
接下来,当你调用TestNG时,把这个jar文件放到类路径上:
$ java -classpath sl.jar:testng.jar org.testng.TestNG testng-single.yaml
Starting
f2 11 2
PASSED: f2("2")
Finishing
这种机制允许您仅通过向类路径添加一个jar文件就可以将同一组侦听器应用到整个组织,而不是要求每个开发人员记住在他们的testng.xml文件中指定这些侦听器。

5.19 - Dependency injection

TestNG支持两种不同类型的依赖注入:原生(由TestNG自身执行)和外部(由Guice等依赖注入框架执行)。

5.19.1 - Native dependency injection

TestNG允许您在方法中声明额外的参数。当发生这种情况时,TestNG将自动用正确的值填充这些参数。依赖注入可以在以下地方使用:
  • 任何@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类型的参数。后一个参数将接收将要调用的测试方法。
你可以用@NoInjection注解来关闭注入:
public class NoInjectionTest {
  @DataProvider(name = "provider")
  public Object[][] provide() throws Exception {
      return new Object[][] { { CC.class.getMethod("f") } };
  }
  @Test(dataProvider = "provider")
  public void withoutInjection(@NoInjection Method m) {
      Assert.assertEquals(m.getName(), "f");
  }
  @Test(dataProvider = "provider")
  public void withInjection(Method m) {
      Assert.assertEquals(m.getName(), "withInjection");
  }
}
下表总结了可以为各种TestNG注解原生注入的参数类型:
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

如果使用Guice, TestNG提供了一种用Guice模块注入测试对象的简单方法:
@Guice(modules = GuiceExampleModule.class)
public class GuiceTest extends SimpleBaseTest {
  @Inject
  ISingleton m_singleton;
  @Test
  public void singletonShouldWork() {
    m_singleton.doSomething();
  }
}
在这个例子中,GuiceExampleModule将接口ISingleton绑定到一些具体的类:
public class GuiceExampleModule implements Module {
  @Override
  public void configure(Binder binder) {
    binder.bind(ISingleton.class).to(ExampleSingleton.class).in(Singleton.class);
  }
}
如果你需要更灵活地指定应该使用哪些模块来实例化你的测试类,你可以指定一个模块工厂:
@Guice(moduleFactory = ModuleFactory.class)
public class GuiceModuleFactoryTest {
  @Inject
  ISingleton m_singleton;
  @Test
  public void singletonShouldWork() {
    m_singleton.doSomething();
  }
}
模块工厂需要实现接口 IModuleFactory:
public interface IModuleFactory {
/**
   * @param context The current test context
   * @param testClass The test class
   *
   * @return The Guice module that should be used to get an instance of this
   * test class.
   */
  Module createModule(ITestContext context, Class<?> testClass);
}
您的工厂将被传递一个测试上下文的实例(ITestComtext)和TestNG需要实例化的测试类。您的createModule方法应该返回一个Guice模块,该模块将知道如何实例化这个测试类。您可以使用测试上下文来找到关于您的环境的更多信息,例如在testng.xml中指定的参数,等等…… 。通过 parent-module 和 guice -stage 套件参数,您将获得更大的灵活性和Guice功能。guice-stage 允许你选择用来创建父注入器的 Stage。默认值是DEVELOPMENT。其他允许的值是 PRODUCTION和TOO L。下面是如何在 test.xml 文件中定义parent-module:
<suite parent-module="com.example.SuiteParenModule" guice-stage="PRODUCTION">
</suite>
TestNG只会为给定套件创建一次此模块。还将使用此模块获取特定于测试的Guice模块实例和模块工厂,然后为每个测试类创建子注入器。通过这种方法,你可以在父模块中声明所有通用的绑定,也可以在模块和模块工厂中注入父模块中声明的绑定。下面是这个功能的一个例子:
package com.example;
public class ParentModule extends AbstractModule {
  @Override
  protected void conigure() {
    bind(MyService.class).toProvider(MyServiceProvider.class);
    bind(MyContext.class).to(MyContextImpl.class).in(Singleton.class);
  }
}
ackage com.example;
public class TestModule extends AbstractModule {
  private final MyContext myContext;
  @Inject
  TestModule(MyContext myContext) {
    this.myContext = myContext
  }
   
  @Override
  protected void configure() {
    bind(MySession.class).toInstance(myContext.getSession());
  }
}
<suite parent-module="com.example.ParentModule">
</suite>
package com.example;
@Test
@Guice(modules = TestModule.class)
public class TestClass {
  @Inject
  MyService myService;
  @Inject
  MySession mySession;
   
  public void testServiceWithSession() {
    myService.serve(mySession);
  }
}
正如你看到的,ParentModule为MyService和MyContext类声明了绑定。然后使用构造函数注入到TestModule类中来注入MyContext,它也为MySession声明绑定。然后test XML文件中的parent-module被设置为ParentModule类,这允许在TestModule中注入。在后面的TestClass中,你会看到两个注入:* MyService -从ParentModule中获取绑定* MySession -从TestModule中获取绑定。这个配置确保了套件中的所有测试都将运行在同一个会话实例中,每个套件只创建一次MyContextImpl对象,这让你有可能为套件中的所有测试配置公共环境状态。

5.20 - Listening to method invocations    

监听器  IInvokedMethodListener 允许您在TestNG将要调用一个测试(用@Test注解的)或配置(用@Before或@After注解的)方法时得到通知。您需要实现以下接口:
public interface IInvokedMethodListener extends ITestNGListener {
  void beforeInvocation(IInvokedMethod method, ITestResult testResult);
  void afterInvocation(IInvokedMethod method, ITestResult testResult);
}
并将其声明为侦听器,这在关于TestNG监听器的一节中有解释( the section about TestNG listeners) 。

5.21 - Overriding test methods

TestNG允许重写甚至跳过测试方法的调用。如果你需要你的测试方法使用特定安全管理其,则可以使用这种方法。你可以通过提供一个实现 IHookable监听器来实现这一点。
下面是JAAS的一个例子:
public class MyHook implements IHookable {
  public void run(final IHookCallBack icb, ITestResult testResult) {
    // Preferably initialized in a @Configuration method
    mySubject = authenticateWithJAAs();
    
    Subject.doAs(mySubject, new PrivilegedExceptionAction() {
      public Object run() {
        icb.callback(testResult);
      }
    };
  }
}

5.22 - Altering suites (or) tests

有时您可能只需要在运行时更改套件xml中的测试标签,而不需要更改套件文件的内容。
这方面的一个经典示例是尝试利用现有的套件文件,并尝试使用它来模拟“被测应用程序”上的负载测试。至少,您将多次复制标记的内容,并创建一个新的套件xml文件并使用它。但这似乎没有太大的规模。
TestNG允许您在运行时通过监听器修改套件xml文件中的套件(或)测试标记。您可以通过提供实现   IAlterSuiteListener 的侦听器来实现这一点。请参考   Listeners section 来了解监听器。
下面是一个示例,展示了如何在运行时更改套件名称:
public class AlterSuiteNameListener implements IAlterSuiteListener {
    @Override
    public void alter(List<XmlSuite> suites) {
        XmlSuite suite = suites.get(0);
        suite.setName(getClass().getSimpleName());
    }
}
这个监听器只能通过以下两种方式添加:
  • 通过套件 xml文件中的<listenters>标签。
  • 通过  Service Loader
不能使用 @Listeners 注解将此监听器添加到执行中。

6 - Test results

6.1 - Success, failure and assert

如果测试完成时没有抛出任何异常,或者抛出了预期的异常(请参阅@Test注解上的expectedExceptions属性的文档),那么测试就被认为是成功的。
您的测试方法通常由可能抛出异常的调用或各种断言(使用Java“assert”关键字)组成。“assert”失败将触发AssertionErrorException,而AssertionErrorException又将该方法标记为失败(如果没有看到断言错误,请记住在JVM上使用-ea)。
下面是一个测试方法的示例:
@Test
public void verifyLastName() {
  assert "Beust".equals(m_lastName) : "Expected name Beust, for" + m_lastName;
}
TestNG还包括JUnit的Assert类,它允许你在复杂的对象上执行断言:
import static org.testng.AssertJUnit.*;
//...
@Test
public void verify() {
  assertEquals("Beust", m_lastName);
}
请注意,上面的代码使用了一个静态导入,以便能够使用assertEquals方法,而不必在它的类前面加上前缀。

6.2 - Logging and results

测试运行的结果创建在一个名为index.html的文件中,该文件位于启动 SuiteRunner 时指定的目录中。该文件指向包含整个测试运行结果的各种其他HTML和文本文件。
用带有Listeners和Reporters的TestNG很容易生成自己的报表:
  • Listeners 实现了 org.testng.ITestListener 接口,并实时通知测试何时开始、通过、失败等等……
  • Reporters 实现了   org.testng.IReporter 接口,并在TestNG运行所有套件时收到通知。IReporter实例接收描述整个测试运行的对象列表。
例如,如果您想生成测试运行的PDF报告,您不需要得到测试运行的实时通知,因此您可能应该使用 IReporter。如果您想要编写测试的实时报告,例如一个GUI,它带有一个进度条,或者一个文本报告器,在每次测试被调用时显示点(“.”)(如下所述),ITestListener是您的最佳选择。

6.2.1— Logging Listeners

下面是一个监听器,它会为每个通过的测试显示一个".",为每个失败显示一个"F",为每个跳过显示一个"S":
public class DotTestListener extends TestListenerAdapter {
  private int m_count = 0;
  @Override
  public void onTestFailure(ITestResult tr) {
    log("F");
  }
  @Override
  public void onTestSkipped(ITestResult tr) {
    log("S");
  }
  @Override
  public void onTestSuccess(ITestResult tr) {
    log(".");
  }
  private void log(String string) {
    System.out.print(string);
    if (++m_count % 40 == 0) {
      System.out.println("");
    }
  }
}
在这个示例中,我选择继承   TestListenerAdapter,它用空方法实现了 ITestListener,因此我不必覆盖接口中我不感兴趣的其他方法。如果愿意,可以直接实现该接口。
下面是我如何调用TestNG来使用这个新的监听器:
java -classpath testng.jar;%CLASSPATH% org.testng.TestNG -listener org.testng.reporters.DotTestListener test\testng.xml
最终将输出:
........................................
........................................
........................................
........................................
........................................
.........................
===============================================
TestNG JDK 1.5
Total tests run: 226, Failures: 0, Skips: 0
===============================================
注意,当您使用 -listener 时,TestNG将自动确定您想要使用的侦听器类型。

6.2.2 - Logging Reporters

  org.testng.IReporter 接口只有一个方法:
public void generateReport(List<ISuite> suites, String outputDirectory)
当所有套件运行完毕后,TestNG将调用该方法,您可以检查它的参数来访问刚刚完成的运行中的所有信息。

6.2.3 - JUnitReports

TestNG包含一个监听器,它接收TestNG结果并输出一个XML文件,然后可以将该文件提供给JUnitReport。 Here 是一个例子,和ant任务一起创建这个报告:
<target name="reports">
  <junitreport todir="test-report">
    <fileset dir="test-output">
      <include name="*/*.xml"/>
    </fileset>
  
    <report format="noframes"  todir="test-report"/>
  </junitreport>
</target>
注意:目前JDK 1.5和JUnitReports之间的不兼容性阻止了框架版本的工作,所以您需要指定“noframes”来让它工作。

6.2.4 - Reporter API

如果你需要记录应该出现在生成的HTML报告中的消息,你可以使用类 org.testng.Reporter:
     Reporter.log ( "M3 WAS CALLED" ) ;
   

6.2.5 - XML Reports

TestNG提供了一个XML报告程序,它捕获了JUnit报告中没有的TestNG特定的信息。当用户的测试环境需要使用带有JUnit格式不能提供的testng特定数据的XML结果时,这特别有用。这个报告器可以通过带有 -reporter 的命令行注入到TestNG中。
下面是一个示例用法:-reporter org.testng.reporters.XMLReporter:generateTestResultAttributes=true,generateGroupsAttribute=true
下表详细介绍了可传递的全部选项。确保使用:
  • :    -将报告名称与其属性分开
  • =  -用于分隔属性的键/值对
  • ,    -用于分隔多个键/值对
下面是这样一个报告的输出样本:
<testng-results>
  <suite name="Suite1">
    <groups>
      <group name="group1">
        <method signature="com.test.TestOne.test2()" name="test2" class="com.test.TestOne"/>
        <method signature="com.test.TestOne.test1()" name="test1" class="com.test.TestOne"/>
      </group>
      <group name="group2">
        <method signature="com.test.TestOne.test2()" name="test2" class="com.test.TestOne"/>
      </group>
    </groups>
    <test name="test1">
      <class name="com.test.TestOne">
        <test-method status="FAIL" signature="test1()" name="test1" duration-ms="0"
              started-at="2007-05-28T12:14:37Z" description="someDescription2"
              finished-at="2007-05-28T12:14:37Z">
          <exception class="java.lang.AssertionError">
            <short-stacktrace>
              <![CDATA[
                java.lang.AssertionError
                ... Removed 22 stack frames
              ]]>
            </short-stacktrace>
          </exception>
        </test-method>
        <test-method status="PASS" signature="test2()" name="test2" duration-ms="0"
              started-at="2007-05-28T12:14:37Z" description="someDescription1"
              finished-at="2007-05-28T12:14:37Z">
        </test-method>
        <test-method status="PASS" signature="setUp()" name="setUp" is-config="true" duration-ms="15"
              started-at="2007-05-28T12:14:37Z" finished-at="2007-05-28T12:14:37Z">
        </test-method>
      </class>
    </test>
  </suite>
</testng-results>
这个报告器与其他默认监听器一起被注入,因此您可以在默认情况下获得这种类型的输出。监听器提供了一些属性,这些属性可以调整报告器以满足您的需求。下表包含了这些属性的列表和简短的解释:
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
为了配置这个报告程序,您可以在命令行中使用-reporter选项,或者使用嵌套<reporter>元素的Ant任务。对于其中的每一个,都必须指定类 org.testng.reporters.XMLReporter。请注意,您不能配置内置报表程序,因为该报表程序将只使用默认设置。如果您只需要带有自定义设置的XML报告,则必须使用两个方法之一手动添加它,并禁用默认监听器。

6.2.6 - TestNG Exit Codes

当TestNG完成执行时,它退出并返回一个返回代码。
可以检查这个返回代码,以了解失败的性质(如果有的话)。
下表总结了TestNG当前使用的不同退出码。
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

TestNG支持   YAML 作为指定套件文件的另一种方法。例如,以下XML文件:
<suite name="SingleSuite" verbose="2" thread-count="4">
  <parameter name="n" value="42" />
  <test name="Regression2">
    <groups>
      <run>
        <exclude name="broken" />
      </run>
    </groups>
    <classes>
      <class name="test.listeners.ResultEndMillisTest" />
    </classes>
  </test>
</suite>
下面是它的YAML版本:
name: SingleSuite
threadCount: 4
parameters: { n: 42 }
tests:
  - name: Regression2
    parameters: { count: 10 } // XML文件中无此配置
    excludedGroups: [ broken ]
    classes:
      - test.listeners.ResultEndMillisTest
这是TestNG自己的套件文件( TestNG's own suite file),以及它的YAML对应文件( YAML counterpart)。
您可能会发现YAML文件格式更易于阅读和维护。TestNG Eclipse插件还可以识别YAML文件。您可以在这篇博客文章( blog post)中找到更多关于YAML和TestNG的信息。
注意:
默认情况下,TestNG不会将与YAML相关的库引入到类路径中。因此,根据您的构建系统(Gradle/Maven),您需要在构建文件中显式地添加对YAML库的引用。
例如,如果你使用Maven,你将需要添加一个依赖如下到你的pom.xml文件:
<dependency>
  <groupid>org.yaml</groupid>
  <artifactid>snakeyaml</artifactid>
  <version>1.23</version>
</dependency>
或者如果你在使用Gradle,你可以像下面这样在你的 build.gradle 中添加一个依赖项:
compile group: 'org.yaml', name: 'snakeyaml', version: '1.23'

8 - Dry Run for your tests(调试运行)

当以调试试运行模式启动时,TestNG将显示一个将被调用但没有实际调用的测试方法列表。
你可以通过传递JVM参数-Dtestng.mode.dryrun=true来为TestNG启用调试运行模式。

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
回到我的 home page
或者看看我的其他项目:
  • EJBGen:EJB标签生成器。
  • TestNG:使用注释、测试组和方法参数的测试框架。
  • Doclipse:一个JavaDoc标签Eclipse插件。
  • J15:一个Eclipse插件,可以帮助您将代码迁移到新的JDK 1.5构造中。
  • SGen:用一个简单的插件架构替代XDoclet。
  • Canvas:一个基于Groovy语言的模板生成器。

10 - Logging framework integration in TestNG

从TestNG 7.5版本开始,TestNG使用 Slf4j 提供的日志框架。
默认情况下,TestNG不会引入任何显式的 Slf4j facade 的实现。
要控制TestNG内部输出的日志,请从 here 添加对任何合适的 Slf4j 实现(本机或封装实现)的依赖

您可能感兴趣的与本文相关的镜像

EmotiVoice

EmotiVoice

AI应用

EmotiVoice是由网易有道AI算法团队开源的一块国产TTS语音合成引擎,支持中英文双语,包含2000多种不同的音色,以及特色的情感合成功能,支持合成包含快乐、兴奋、悲伤、愤怒等广泛情感的语音。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值