【译】TestNG官方文档中文版(08)—— 测试方法、测试类和测试组(5.13-5.20)
2011-02-22 10:23
501 查看
5.13 - 程序化运行TestNG
你可以在程序中非常轻松的调用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.xml 文件来调用。为此,你可以使用这个包 org.testng.xml中的类: XmlClass、XmlTest等等。每个类都对应了其在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.14 - BeanShell于高级组选择
如果 <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 脚本的额外说明:
必须返回一个boolean值。除了这个约束以外,任何有效的 BeanShell 代码都是允许的 (例如,可能需要在工作日返回 true 而在周末返回 false,这样就允许你可以依照不同的日期进行测试)。
TestNG 定义了如下的变量供你调用:
java.lang.reflect.Method method: 当前的测试方法
org.testng.ITestNGMethod testngMethod: 当前测试方法的描述
java.util.Map<String, String> groups: 当前测试方法所属组的映射
你也可能需要使用 CDATA 声明来括起Beanshell表达式(就像上例)来避免对XML保留字冗长的引用。
5.15 - 注解转换器
TestNG 允许你在运行时修改所有注解的内容。在源码中注解大多数时候都能正常工作的时时非常有用的(这句原文就是这意思,感觉不太对劲),但是有几个情况你可能会改变其中的值。为此,你会用到注解转换器( 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. * * Note that only one of the three parameters testClass, * testConstructor and testMethod will be non-null. * * @param annotation The annotation that was read from your * test class. * @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 参数中的设置方法来在进一步处理之前改变它的值。
例如,这里是你如何覆盖属性 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 注解。如果你需要修改其他的(假设说配置注解@Factory 或 @DataProvider),使用 IAnnotationTransformer2。
5.16 - 方法拦截器
一旦TestNG 计算好了测试方法会以怎样的顺序调用,那么这些方法就会分为两组:按照顺序运行的方法。这里所有的方法都有相关的依赖,并且所有这些方法按照特定顺序运行。
不定顺序运行的方法。这里的方法不属于第一个类别。方法的运行顺序是随机的,下一个说不准是什么(尽管如此,默认情况下TestNG会尝试通过类来组织方法)。
为了能够让你更好的控制第二种类别,TestNG定义如下接口:
public interface IMethodInterceptor { List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context); }
方法中叫做methods的那个列表参数包含了所有以不定序运行的方法。你的 intercept 方法也要返回一个 IMethodInstance列表,它可能是下面情况之一:
内容与参数中接收的一致,但是顺序不同
一组 IMethodInstance 对象
更大的一组 IMethodInstance 对象
一旦你定义了拦截器,就把它传递个TestNG,用下面的方式:
java -classpath "testng-jdk15.jar:test/build" org.testng.TestNG -listener test.methodinterceptors.NullMethodInterceptor / -testclass test.methodinterceptors.FooTest
关于 ant 中对应的语法,参见 listeners 属性 ant 文档 中的说明。
例如,下面是个方法拦截器会重新给方法排序,一遍“fast”组中的方法总是先执行:
public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) { List<IMethodInstance> result = new ArrayList<IMethodInstance>(); for (IMethodInstance m : methods) { Test test = m.getMethod().getMethod().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.17 - 从JavaDoc 注解迁移到JDK 注解
如果项目伊始使用了javadoc annotations,但是之后要转换到JDK annotations,这样需要把所有这些都进行转换。TestNG 提供了一个工具来帮你做这些。
java org.testng.AnnotationConverter -srcdir directory [-overwrite|-d destdir] [-quiet]
上述命令会把源文件从一个格式转换到另外一个。如果不带参数运行,就会显示所有参数的用法。
注意,转换后的文件,可能不是非常漂亮,所以要检查一下其正确性。所以最好用版本控制工具,如果不喜欢可以撤销操作!转换器本身也假设你使用了上面 所推荐的语法规约。
5.18 - TestNG 监听器
有很多接口可以用来修改 TestNG 的行为。这些接口都被统称为 "TestNG 监听器"。下面是目前支持的监听器的列表:IAnnotationTransformer (doc, javadoc)
IReporter (doc, javadoc)
ITestListener (doc, javadoc)
IMethodInterceptor (doc, javadoc)
IInvokedMethodListener (doc, javadoc)
当你实现了这些接口,你可以让 TestNG 知道这些接口,有如下方式:
在命令行下使用 -listener
ant中使用 <listeners>
在 testng.xml 中使用 <listeners> 标签
下面是第三种方式的例子:
<suite> <listeners> <listener class-name="com.example.MyListener" /> <listener class-name="com.example.MyMethodInterceptor" /> </listeners> ...
5.19 - 依赖注入
TestNG 允许你在自己的方法中声明额外的参数。这时,TestNG会自动使用正确的值填充这些参数。依赖注入就使用在这种地方:任何 @Before 或 @Test 方法可以声明一个类型为 ITestContext 的参数。
任何 @After 都可以声明一个类型为 ITestResult 的单数,它代表了刚刚运行的测试方法。
任何 @Before 和 @After 方法都能够声明类型为 XmlTest 的参数,它包含了当前的 <test> 参数。
任何 @BeforeMethod 可以声明一个类型为 java.lang.reflect.Method 的参数。这个参数会接收 @BeforeMethod 完成调用的时候马上就被调用的那个测试方法当做它的值。
任何 @BeforeMethod 可以声明一个类型为 Object[] 的参数。这个参数会包含要被填充到下一个测试方法中的参数的列表,它既可以又 TestNG 注入,例如 java.lang.reflect.Method 或者来自 @DataProvider。
任何 @DataProvider 可以声明一个类型为 ITestContext 或 java.lang.reflect.Method 的参数。后一种类型的参数,会收到即将调用的方法作为它的值。
5.20 - 监听方法调用
无论何时TestNG即将调用一个测试(被@Test注解的)或者配置(任何使用 @Before or @After 注解标注的方法),监听器 IInvokedMethodListener 都可以让你得到通知。你所要做的就是实现如下接口:public interface IInvokedMethodListener extends ITestNGListener { void beforeInvocation(IInvokedMethod method, ITestResult testResult); void afterInvocation(IInvokedMethod method, ITestResult testResult); }
并且就像在 关于TestNG监听器一节 中所讨论的那样,将其声明为一个监听器。
相关文章推荐
- 【译】TestNG官方文档中文版(08)—— 测试方法、测试类和测试组
- TestNG官方文档中文版(05)—— 测试方法、测试类和测试组
- 【译】TestNG官方文档中文版(05)—— 测试方法、测试类和测试组(5.1-5.4)
- 【译】TestNG官方文档中文版(06)—— 测试方法、测试类和测试组(5.5-5.6)
- 【译】TestNG官方文档中文版(07)—— 测试方法、测试类和测试组(5.7-5.12)
- TestNG官方文档中文版(5)-测试方法/类和组
- TestNG官方文档中文版(5)-测试方法/类和组
- TestNG官方文档中文版(5)-测试方法/类和组
- TestNG官方文档中文版(06)—— 测试结果
- TestNG官方文档中文版(7)-方法依赖和工厂
- 【译】TestNG官方文档中文版(09)—— 测试结果
- TestNG官方文档中文版(8,9)-类级别注解和并发,重复失败测试,junit测试,jdk1.4支持,编程式调用和Beanshell
- TestNG指南5-测试方法、测试类与测试组
- 【译】TestNG官方文档中文版(11)—— TestNG的Eclipse插件
- TestNG系列-第五章 测试方法、测试类和测试分组(续4)-工厂
- 【译】TestNG官方文档中文版(01)—— 简介
- 【译】TestNG官方文档中文版(12)—— TestNG的Maven插件
- TestNG官方文档中文版(2)-annotation
- TestNG系列-第五章 测试方法、测试类和测试分组(续8)-监听器
- 【译】TestNG官方文档中文版(13)—— TestNG 与 Ant任务