目录
(一)TestNG学习之路—HelloWorld入门
(二)TestNG学习之路—注解及属性概览
(三)TestNG学习之路—TestNG.xml/YAML
(四)TestNG学习之路—注解详述之@Test
(五)TestNG学习之路—注解详述之参数化
(六)TestNG学习之路—注解详述之@Factory
(七)TestNG学习之路—注解详述之忽略测试
(八)TestNG学习之路—注解详述之并发
(九)TestNG学习之路—失败测试重跑
(十)TestNG学习之路—编码执行TestNG
(十一)TestNG学习之路—BeanShell高级用法
(十二)TestNG学习之路—注解转换器
(十三)TestNG学习之路—方法拦截器
(十四)TestNG学习之路—TestNG监听器
(十五)TestNG学习之路—依赖注入
(十六)TestNG学习之路—测试报告
(十七)基于TestNG+Rest Assured+Allure的接口自动化测试框架
前言
TestNG允许您在测试执行时修改所有注解(@Test,@DataProvider,@Factory等)的内容,可以通过重写IAnnotationTransformer,IAnnotationTransformer2 的方法来实现。IAnnotationTransformer 只能用来修改 @Test 注解,如果需要修改其他 TestNG 的注解(比如@DataProvider, @Factory 以及 @Configuration),需要使用 IAnnotationTransformer2 监听器。
示例
IAnnotationTransformer
通过javadoc可发现,IAnnotationTransformer继承了ITestNGListener接口,其要求实现transform方法。
public interface IAnnotationTransformer extends ITestNGListener{
/**
* 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);
}
通过重写transform方法,可改写@Test注解的属性,示例如下:
编写测试类如下:
import org.testng.annotations.Test;
public class TestTransform {
@Test
public void test(){
System.out.println("Test annotationTransformer!");
}
}
IAnnotationTransformer实现类如下:
import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Transform implements IAnnotationTransformer {
public void transform(ITestAnnotation iTestAnnotation, Class aClass, Constructor constructor, Method method) {
iTestAnnotation.setInvocationCount(2); //执行2次
}
}
testng.xml配置如下:
执行结果如下:
Test annotationTransformer!
Test annotationTransformer!
===============================================
All Test Suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
如上结果所示,可发现@Test注解的方法执行了2次,说明Transform监听器起了作用。
IAnnotationTransformer2
public interface IAnnotationTransformer2 extends IAnnotationTransformer {
void transform(IConfigurationAnnotation var1, Class var2, Constructor var3, Method var4);
void transform(IDataProviderAnnotation var1, Method var2);
void transform(IFactoryAnnotation var1, Method var2);
}
IAnnotationTransformer2继承IAnnotationTransformer接口,其可以用于修改@DataProvider,@Factory,@Configuration注解,但@Configuration在新版本已经被@BeforeSuite,@AfterSuite 等代替,所以此处不再探讨。
编写测试类:
import org.testng.annotations.Test;
public class TestTransform {
private String str;
public TestTransform(String str){
this.str = str;
}
@Test()
public void test(){
System.out.println("Test annotationTransformer!");
System.out.println("DataProviderName:"+str);
}
}
编写工厂类,该工厂类有两个dataProvider(tom,data),默认使用tom。
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
public class TransformFactory {
@Factory(dataProvider = "tom")
public Object[] transformFac(String str){
Object[] objects = new Object[1];
for(int i=0;i<1;i++){
TestTransform testTransform = new TestTransform(str);
objects[i] = testTransform;
}
return objects;
}
@DataProvider(name = "tom")
public Object[][] tom(){
return new Object[][]{new Object[]{"tom"}};
}
@DataProvider(name = "data")
public Object[][] data(){
return new Object[][]{new Object[]{"data"}};
}
}
编写IAnnotationTransformer2实现类如下,用于修改Factory的dataProvider为data。
import org.testng.IAnnotationTransformer2;
import org.testng.annotations.IConfigurationAnnotation;
import org.testng.annotations.IDataProviderAnnotation;
import org.testng.annotations.IFactoryAnnotation;
import org.testng.annotations.ITestAnnotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Transform2 implements IAnnotationTransformer2 {
public void transform(IConfigurationAnnotation iConfigurationAnnotation, Class aClass, Constructor constructor, Method method) {
}
public void transform(IDataProviderAnnotation iDataProviderAnnotation, Method method) {
if (iDataProviderAnnotation.getName().equals("tom")) //匹配名为data的DataProvider
iDataProviderAnnotation.setParallel(true); //设置并行
}
public void transform(IFactoryAnnotation iFactoryAnnotation, Method method) {
iFactoryAnnotation.setDataProvider("data");
}
public void transform(ITestAnnotation iTestAnnotation, Class aClass, Constructor constructor, Method method) {
}
}
编写testng.xml(不使用监听器)如下:
执行结果如下:
Test annotationTransformer!
DataProviderName:tom
===============================================
Default Suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
修改testng.xml(使用监听器)如下:
执行结果如下:
Test annotationTransformer!
DataProviderName:data
===============================================
All Test Suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
对比以上两个执行结果,可发现@Factory的dataProvider确实被修改了。
注意事项
@listener注解不能包含IAnnotationTransformer和IAnnotationTransformer2的实现类,原因是这两种监听器必须在更早的阶段添加到 TestNG 中才能实施修改注释的操作,所以它们只能在 testng.xml 添加。还是最前面的例子,通过以下方式添加监听器不会起作用。
@Listeners(Transform.class)
public class TestTransform {
@Test
public void test(){
System.out.println("Test annotationTransformer!");
}
}