1. 介绍
在欢迎页面上可以找到快速入门示例。
下面是这篇文档使用的概念:
这份手册的剩余部分将讲述以下内容:
*******************************************************************************
注:上面的内容很简短,但是请注意其中的一些细节。
1. TestNG是一个设计用来简化广泛的测试需求的测试框架,从单元测试到集成测试
2. 测试的过程的三个典型步骤,注意和junit(4.0)相比,多了一个将测试信息添加到testng.xml文件或者build.xml
3. 基本概念,相比junit的TestCase/TestSuite,TestNG有suite/test/test method三个级别,即将test/test method明确区分开了。
2 - Annotation
这里是TestNG中用到的annotation的快速预览,还有它们的属性。
@BeforeSuite:
@AfterSuite:
@BeforeTest:
@AfterTest:
@BeforeGroups:
@AfterGroups:
@BeforeClass:
@AfterClass:
@BeforeMethod:
@AfterMethod:
属性:
@DataProvider
@Factory
@Parameters
@Test
注:
1. before方法和after方法
2. dependsOnGroups/dependsOnMethods 提供了依赖检查机制,并可以严格控制执行顺序
3. DataProvider 使得对同一个方法的测试覆盖变的非常轻松,非常适合进行边界测试,只要给出多种测试数据就可以针对一个测试方法进行覆盖
4. expectedExceptions 使得异常测试变的非常轻松
5. invocationCount/threadPoolSize 终于可以简单的直接进行多线程测试了,这个绝对是junit的超级弱项,回想junit中那个万恶的System.exist(0)...
6. timeOut 终于不用死等然后手工强行关闭测试,TestNG想的太周到了
TestNG官方文档中文版(3)-testng.xml
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1"
</suite>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1" >
</suite>
<test name="Regression1">
</test>
4 - 运行TestNG
TestNG可以以不同的方式调用:
1) 命令行
假设你已经将TestNG加入到class path,调用TestNG最简单的方法事下面的:
java org.testng.TestNG testng1.xml [testng2.xml testng3.xml ...]
必须指定最少一个描述你试图测试的TestNG suite的xml文件。另外,下面的命令行参数可以使用:
命令行参数列表
选项
-d
-sourcedir
-testclass
-groups
-excludegroups
-testrunfactory
-listener
-parallel
-threadcount
-suitename
-testname
-reporter
可以通过不带任何参数直接调用TestNFG来获得这个文档。
可以将命令行开关写到txt文件中,例如c:\command.txt, 然后告诉TestNG使用这个文件类找到参数:
另外,可以通过jvm的命令行来传递参数给TestNG,例如
java -Dtestng.test.classpath="c:/build;c:/java/classes;" org.testng.TestNG testng.xml
TestNG能够理解的参数
属性
testng.test.classpath
举例:
java org.testng.TestNG -groups windows,linux -testclass org.test.MyTest
注意 ant 任务和testng.xml容许用更多的参数来启动TestNG(包含的方法,指定的参数,等等),因此可以认为命令行适用于学习TestNG并且想快速入门。
2) Ant
可以这样定义TestNG的ant任务:
<taskdef resource="testngtasks"
这个任务运行TestNG测试,并且通常是在单独的jvm中。接受下面的属性:
属性名
annotations
classfilesetref
classpath
classpathref
dumpCommand
enableAssert
failureProperty
haltonfailure
haltonskipped
groups
excludedgroups
jvm
listeners
outputdir
skippedProperty
sourcedir
sourcedirref
suiteRunnerClass
parallel
threadCount
testJar
timeOut
useDefaultListeners
workingDir
xmlfilesetref
suitename
testname
属性classpath, classpathref或者内嵌的<classpath>必须设置一个,用于提供测试的classpath
属性xmlfilesetref, classfilesetref 或者内嵌的 <xmlfileset>, 分别的<classfileset>必须使用用来提供测试
注意:如果使用jdk1.4,属性attributes sourcedir, sourcedirref 或者内嵌的 <sourcedir> 必须提供.
注意:使用<classfileset> 并不自动按添加测试类到classpath: 需要报告这些在classpath中的任务要工作的类
内嵌元素
classpath
bootclasspath
bootstrap类文件的位置可以用这个PATH形式的结构指定-如果fork没有设置则被忽略
xmlfileset
套餐定义(testng.xml)可以通过一个FiltSet结构传递给任务
classfileset
TestNG可以直接在类上运行,同样支持FiltSet结构
sourcedir
PATH形式的结构,用于jdk1.4的测试,使用javadoc annotation
jvmarg
通过内嵌的<jvmarg>元素将额外的参数传递给新的虚拟机,例如:
<testng>
</testng>
sysproperty
使用内嵌的<sysproperty>元素来指定类需要的系统属性。在测试的执行期间虚拟机可以获取这些属性。这个元素的属性和环境变量相同。
<testng>
</testng>
将运行测试并且使得测试可以访问basedir属性
reporter
内部的<reporter>元素是一个可选的方式,用于注入自定义的报告监听器,容许用户为调整运行时的报告期行为而
这个元素强制要求设置classname属性,指示自定义监听器的类。为了设置报告期属性,<reporter>元素可以包含多个内嵌的<property>元素来提供name和value属性,如下所示:
<testng ...>
</testng>
public class MyReporter {
}
请注意这里仅仅支持有限的属性类型:String, int, boolean, byte, char, double, float, long, short.
env
可以通过内嵌的 <env>元素给TestNG的单独的虚拟机传递指定的环境变量。
要查阅<env> 元素属性的详细描述,请查看ant的exec任务的描述。
举例:
Suite xml
<testng classpathref="run.cp"
</testng>
Class FileSet
<testng classpathref="run.cp"
public Iterator createData() {
)
@DataProvider(name = "test1")
public Iterator createData() {
}
如果将测试方法的第一个参数申明为java.lang.reflect.Method,TestNG将使用这个第一个参数来传递当前测试方法。当多个测试方法使用同一个@DataProvider而需要依当前申请数据的方法而定来返回不同值时特别有用。
举例说明,下面的代码在@DataProvider中打印测试方法的名字:
@DataProvider(name = "dp")
public Object[][] createData(Method m) {
}
@Test(dataProvider = "dp")
public void test1(String s) {
}
@Test(dataProvider = "dp")
public void test2(String s) {
}
将会显示:
5.6 - Dependent methods
有些时候,你需要你的测试方法按照一个特定的顺序被调用。这非常有用,比如:
为了做到这点,需要使用@Test注解的dependsOnMethods属性或者dependsOnGroups属性。
有两种依赖:
这里有一个强依赖的例子:
@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()前被调用。
注意:前面说明说,在测试运行期间,属于同一个组的方法的调用顺序并不保证相同。如果一个方法的依赖失败了,而且是强依赖(默认alwaysRun=false),这个方法将不被标记为FAIL而是SKIP。被跳过的方法在最终的报告中报告(在HTML中用红和绿之外的其他颜色),这很重要,因为被跳过的方法并不一定是失败。
dependsOnGroups和dependsOnMethods都接受正则表达式作为参数。对于dependsOnMethods, 如果你依赖的方法巧合有多个重载的版本,所有装载的方法都将被调用。如果你只想调用重载的方法中的一个,请使用dependsOnGroups。
有关方法依赖的更高级的例子,请参考本文档,将使用继承来提供一个优雅的解决方案来处理多重依赖的问题。
5.7 - Factories
工厂类容许你动态创建测试案例。例如,想象你需要创建一个测试方法,访问一个web站点上的页面很多次,而你希望用不同的值来调用它:
public class TestWebServer {
}
testng.xml:
<test name="T1">
</test>
<test name="T2">
</test>
<test name="T3">
</test>
这种方式很快就会变的难于管理,所以作为替换品,你可以使用factory:
public class WebTestFactory {
}
而新的测试类是这样:
public class WebTest {
}
testng.xml只需要引用简单引用这个包含factory方法的类,因为测试实例将在运行时被创建。
<class name="WebTestFactory" />
工厂类将像@Test和@Before/After一样接收参数,必须返回Object[]。返回的对象可以是任何类(不一定要求是和factory类一样),并且他们甚至都不需要包含TestNG的注解(这种情况下他们将被testNG忽略)。
5.8 - Class level annotations
@Test注解可以放置在类上:
@Test
public class Test1 {
}
类级别注解的效果是将这个类的所有的public方法都变成测试方法,即使他们没有被注解。还可以在需要增加属性的方法上重复@Test注解。
例如:
@Test
public class Test1 {
}
将方法test1()和test2()都变成测试方法,但是在此之上,test2()现在属于组"g1".
5.9 - Parallel running and time-outs
可以通过使用parallel属性要求TestNG在单独的线程中运行测试。这个属性可以在两个值中取其一:
<suite name="My suite" parallel="methods" thread-count="5">
<suite name="My suite" parallel="tests" thread-count="5">
@Test(threadPoolSize = 3, invocationCount = 10,
public void testServer() {
}
在这个例子中,方法testServer将被3个不同线程调用10次。此外,10秒种的time-out属性保证任何线程都不会长时间阻塞。
5.10 - Rerunning failed tests
套件中的测试失败时,每次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将包含所有必要的依赖方法,所以可以保证运行失败的方法而不运行任何被跳过的(失败)方法。
5.11 - JUnit tests
TestNG可以运行junit测试。所需要的只是在testng.classNames属性中指定junit测试类,并设置testng.junit属性为true。
<test name="Test1"
这种情况下TestNG的行为类似jnit:
5.12 - JDK 1.4
TestNG也可以在JDK1.4下工作。在这种情况下,需要使用发布的jdk1.4的jar文件(名为testng-...-jdk14.jar)。唯一的差别是在于注解,jdk1.4下使用流行的XDoclet javadoc注解语法:
public class SimpleTest {
}
javadoc语法的规则非常简洁,和jdk1.5注解的唯一差别是数组串数组需要特别写成单独的,逗号或空格分隔的字符串。虽然值周围的双引号是可选的,但还是建议在任何情况下都使用双引号,以保证将来迁移到jdk1.5时可以比较容易。
同样需要在<testng>的ant任务中指明sourcedir属性(或者在命令行中使用-sourcedir),以便testNG可以找到你的测试文件的源代码来解析javadoc注解。
这里是jdk1.4和jdk5注解的语法对照表:
更多jdk1.4的支持范例,请参考发行包中的test-14文件夹,这里包含全部的JDK 1.5测试对应的使用javadoc注解的内容。
5.13 - 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包的类:XmlClass, XmlTest, 等等。每个类对应他们xml标签。
例如,假设你想创建下面的虚拟文件:
<suite name="TmpSuite" >
</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();
完整的API请参考javadoc。
5.14 - BeanShell and advanced group selection
如果testng.xml中的<include>和<exclude>标签还不足够满足你的需要,你可以使用BeanShell表达式来决定是否需要将一个特定的测试方法包含在测试操作中。只需要在<test>标签下指定这个表达式:
当发现testng.xml中有<script>标签,TestNG将忽略当前<test>标签中的以后的组和方法的<include>和<exclude>标签:BeanShell表达式将是决定一个测试方法是否包含的唯一方法。
这里有一些BeanShell脚本的额外信息:
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wzh0439/archive/2009/05/18/4197806.aspx
附 : testNG Annotations 参考
@BeforeSuite @AfterSuite @BeforeTest @AfterTest @BeforeGroups @AfterGroups @BeforeClass @AfterClass @BeforeMethod @AfterMethod | TestNG 类的配置信息: @BeforeSuite: 被注解的方法,会在当前suite中所有测试方法之 前 被调用。 @AfterSuite: 被注解的方法,会在当前suite中所有测试方法之 后 被调用。 @BeforeTest: 被注解的方法,会在测试(原文就是测试,不是测试方法)运行 前 被调用 @AfterTest: 被注解的方法,会在测试(原文就是测试,不是测试方法)运行 后 被调用 @BeforeGroups: 被注解的方法会在组列表中之前被调用。这个方法会在每个组中第一个测试方法被调用之前被调用。 @AfterGroups: 被注解的方法会在组列表中之后被调用。这个方法会在每个组中最后一个测试方法被调用之后被调用。 @BeforeClass: 被注解的方法,会在当前类第一个测试方法运行前被调用 @AfterClass: 被注解的方法,会在当前类所有测试方法运行后被调用 @BeforeMethod: 被注解的方法,会在运行每个测试方法之前调用 @AfterMethod: 被注解的方法,会在每个测试方法运行之后被调用 | |
alwaysRun | 对于在方法之前的调用(beforeSuite, beforeTest, beforeTestClass 和 beforeTestMethod, 除了beforeGroups): 若为true,这个配置方法无视其所属的组而运行 对于在方法之后的调用(afterSuite, afterClass, ...): 若为true, 这个配置方法会运行,即使其之前一个或者多个被调用的方法失败或者被跳过。 | |
dependsOnGroups | 方法所依赖的一组group列表 | |
dependsOnMethods | 方法所依赖的一组method列表 | |
enabled | 在当前class/method中被此annotation标记的方法是否参与测试(不启用则不在测试中运行) | |
groups | 一组group列表,指明了这个class/method的所属。 | |
inheritGroups | 如果是true,则此方法会从属于在类级由@Test注解中所指定的组 | |
@DataProvider | 把此方法标记为为测试方法提供数据的方法。被此注释标记的方法必须返回Object[][],其中的每个Object[]可以被分配给测试方法列表中的方法当做参数。那些需要从DataProvider接受数据的@Test方法,需要使用一个dataprovider名字,此名称必须与这个注解中的名字相同。 | |
name | DataProvider的名字 | |
@Factory | 把一个方法标记为工厂方法,并且必须返回被TestNG测试类所使用的对象们。 此方法必须返回 Object[]。 | |
@Parameters | 说明如何给一个 @Test 方法传参。 | |
value | 方法参数变量的列表 | |
@Test | 把一个类或者方法标记为测试的一部分。 | |
alwaysRun | 如果为true,则这个测试方法即使在其所以来的方法为失败时也总会被运行。 | |
dataProvider | 这个测试方法的dataProvider | |
dataProviderClass | 指明去那里找data provider类。如果不指定,那么就当前测试方法所在的类或者它个一个基类中去找。如果指定了,那么data provider方法必须是指定的类中的静态方法。 | |
dependsOnGroups | 方法所依赖的一组group列表 | |
dependsOnMethods | 方法所以来的一组method列表 | |
description | 方法的说明 | |
enabled | 在当前class/method中被此annotation标记的方法是否参与测试(不启用则不在测试中运行) | |
expectedExceptions | 此方法会抛出的异常列表。如果没有异常或者一个不在列表中的异常被抛出,则测试被标记为失败。 | |
groups | 一组group列表,指明了这个class/method的所属。 | |
invocationCount | 方法被调用的次数。 | |
invocationTimeOut | 当前测试中所有调用累计时间的最大毫秒数。如果invocationCount属性没有指定,那么此属性会被忽略。 | |
successPercene | 当前方法执行所期望的success的百分比 | |
sequential | 如果是true,那么测试类中所有的方法都是按照其定义顺序执行,即使是当前的测试使用parallel="methods"。此属性只能用在类级别,如果用在方法级,就会被忽略。 | |
timeOut | 当前测试所能运行的最大毫秒数 | |
threadPoolSize | 此方法线程池的大小。 此方法会根据制定的invocationCount值,以多个线程进行调用。 注意:如果没有指定invocationCount属性,那么此属性就会被忽略 |