15 注解变形(
Annotation Transformers
)
TestNG允许在运行的时候修改所有的注解的内容。当源代码的注解是正确的时候,这方法特别有用(
This is especially useful if the annotations in the source code are right most of the time),但是也有一些需要重写值的情况。
为了实现这一情况,需要使用注解变形器
(
Annotation Transformers
)
注解变形器是一个实现了下面接口的类:
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());// ...
当方法tramsform()被调用的时候,我们能调用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
16 方法拦截器(
Method Interceptors
)
一旦TestnG已经开始执行,测试方法按照某种顺序执行,这些方法会被分为两组:
- 方法顺序运行。所有的方法是独立或者依赖的。这些方法会以指定顺序执行
- 方法无特定顺序运行。所有的这些方法都不属于第一类。这些测试方法运行的顺序是随机的。(默认情况下,TestNG会尝试对测试方法以类进行分组)。
为了更好的控制第二类测试方法的运行,TestNG定义了如下接口:
public interface IMethodInterceptor {
List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context);
}
传入的方法列表可以以任何顺序执行。我们的拦截(
intercept)方法被期望返回一个相似的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
.中属性listeners
下面是对方法进行再排序的的方法拦截器,属于分组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;
}