There are several interfaces that allow you to modify TestNG's behavior. These interfaces are broadly called "TestNG Listeners". Here are a few listeners:
When you implement one of these interfaces, you can let TestNG know about it with either of the following ways:
- IAnnotationTransformer (doc, javadoc)
- IAnnotationTransformer2 (doc, javadoc)
- IHookable (doc, javadoc)
- IInvokedMethodListener (doc, javadoc)
- IMethodInterceptor (doc, javadoc)
- IReporter (doc, javadoc)
- ISuiteListener (doc, javadoc)
- ITestListener (doc, javadoc)
- Using -listener on the command line.
- Using <listeners> with ant.
- Using <listeners> in your testng.xml file.
- Using the @Listeners annotation on any of your test classes.
- Using ServiceLoader.
目录
监听器介绍
尽管TestNG已经为我们提供了很强大的功能和灵活的选项,但没有一种方法是能够完全解决我们所有的问题。在实际应用中,我们多多少少会发现一些TestNG自带功能无法满足我们实际需求的情况。TestNG为我们提供了一些接口允许我们修改TestNG的行为。这些接口通常被称为“TestNG监听器”。这些监听器是
- IAnnotationTransformer
- IAnnotationTransformer2
- IHookable
- IInvokedMethodListener
- IMethodInterceptor
- IReporter
- ISuiteListener
- ITestListener
虽然叫监听器,但事实上它们只是一些预定义的Java接口。我们创建这些接口的实现类,并将它们加入到TestNG中,TestNG 便会在测试运行的不同时刻调用这些类中的接口方法。
监听器分类
接下来,我们一一介绍 TestNG 中的每种监听器
IAnnotationTransformer
TestNG提供了三个IAnnotationTransformer系列的监听器,这3个监听器的目的都是在TestNG执行过程中动态改变测试类中Annotation的参数。其区别在于不同的IAnnotationTransformer监听器,能够操作的Annotation不同,具体情况如下:
IAnnotationTransformer 只能用来修改 @Test 注释,IAnnotationTransformer 要求实现 transform 方法,其方法签名如下:
void transform(ITestAnnotation var1, Class var2, Constructor var3, Method var4);
var1代表的就是testMethod定义的@Test注释,调用其方法可以更改@Test注释属性,例如下面代码可以让我们在运行时将属性enabled改为false,从而禁用当前测试方法
public class AnnotationTransformer implements IAnnotationTransformer {
@Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
annotation.setEnabled(false);
}
}
IAnnotationTransformer2
IAnnotationTransformer2 监听器是用来在运行时修改@DataProvider, @Factory 以及 @Configuration。下面是该监听器要求实现的方法。
void transform(IConfigurationAnnotation var1, Class var2, Constructor var3, Method var4);
void transform(IDataProviderAnnotation var1, Method var2);
void transform(IFactoryAnnotation var1, Method var2);
@Configuration 在最新版本中已不被推荐使用,需用 @BeforeSuite,@AfterSuite 等注释替代。
IAnnotationTransformer3
该监听器用来在运行时,修改@Listeners标注
public interface IAnnotationTransformer3 extends IAnnotationTransformer2 {
void transform(IListenersAnnotation var1, Class var2);
}
IHookable
IHookable 监听器提供了类似与面向方面编程(AOP)中的 Around Advice 的功能。它在测试方法执行前后提供了切入点,从而使用户能够在测试方法运行前后注入特定的功能。例如,用户可以在当前测试方法运行前加入特定的验证逻辑以决定测试方法是否运行或者跳过,甚至覆盖测试方法的逻辑。下面是 IHookable 监听器要求实现的方法签名。
void run(IHookCallBack var1, ITestResult var2);
IInvokedMethodListener
与 IHookable 类似,IInvokedMethodListener 提供了类似与面向方面编程(AOP)中的 Before Advice 和 After Advice 的功能。它允许用户在当前测试方法被执行前和执行后注入特定的逻辑,比如,可以加入日志方法。用户需要实现的方法如下
// 测试类中每个测试方法执行前运行一遍
void beforeInvocation(IInvokedMethod var1, ITestResult var2);
// 测试类中每个测试方法执行后运行一遍
void afterInvocation(IInvokedMethod var1, ITestResult var2);
IInvokedMethodListener2
与IInvokedMethodListener功能一样,方法的参数列表增加了 ITestContext 参数
IMethodInterceptor
TestNG 通过 @Test 注释中的 dependsOnGroups 和 dependsOnMethods 使用户能够定义测试方法之间的依赖关系。我们根据测试方法的执行顺序,将测试方法分为两类
第一类,顺序执行的方法,有明确的依赖关系,依赖于其他测试方法或者被其他测试方法所依赖的方法
第二类,无特定熟悉怒的方法,无依赖关系,谁先执行谁后执行没有要求
对于第二类中的测试方法,尽管默认 TestNG 会尝试用类名将它们分组,但是理论上,它们的运行顺序是随机的,甚至每次运行的顺序都可能不同。因此为了使用户拥有对第二类测试方法更大的控制权,IMethodInterceptor 监听器产生了。该监听器可以让我们改变测试方法的执行顺序,用户要实现的方法如下。
List<IMethodInstance> intercept(List<IMethodInstance> var1, ITestContext var2);
intercept 方法在所有测试方法被分类后以及所有测试方法被执行前被调用。因此,用户在 intercept 方法中可以对列表进行修改,比如重新排序,甚至增加或者减少测试方法
最终,所有的测试方法将按照 intercept 返回值列表中的顺序被执行 。
需要注意:只有第二类测试方法能够作为intercept()方法的第一个参数。
IReporter
TestNG 提供了默认的测试报表。也提供了IReporter 监听器。只要实现这个接口,并加上监听,就可以拿到所有测试信息,可以用来自定义测试报告。IReporter 监听器只有一个方法需要实现。
void generateReport(List<XmlSuite> var1, List<ISuite> var2, String var3);
该方法在所有测试方法执行结束后被调用,通过遍历 xmlSuites 和 suites 能够获取所有测试方法的信息以及测试结果。outputDirectory 是默认的测试报表生成路径,当然你可以指定其他路径生成报表。
ISuiteListener
ISuiteListener 类似于 IInvokedMethodListener,区别是 IInvokedMethodListener 针对的是测试方法,而ISuiteListener 针对的是测试套件。ISuiteListener使用户有机会在测试套件开始执行以及执行结束之后嵌入自己的逻辑。该监听器要求实现的方法如下。
void onStart(ISuite var1);
void onFinish(ISuite var1);
ITestListener
如果要在测试方法执行成功、失败或者跳过时指定不同后续行为,可以通IInvokedMethodListener 实现,不过更为简便的方式是利用 ITestListener 监听器。ITestListener 监听器要求实现的方法如下
void onTestStart(ITestResult var1);
void onTestSuccess(ITestResult var1);
void onTestFailure(ITestResult var1);
void onTestSkipped(ITestResult var1);
void onTestFailedButWithinSuccessPercentage(ITestResult var1);
void onStart(ITestContext var1);
void onFinish(ITestContext var1);
另外,TestListenerAdapter 已经实现 ITestListener,并且提供了一些有用的方法,比如分别获取所有成功失败跳过三种测试结果的测试方法的方法,并且 ITestListner 中有很多方法在TestListenerAdapter 已给出了默认实现。因此,继承 TestListenerAdapter 后,便只需关注需要修改的方法。
监听器的使用
【1】直接在测试类中引入,Listener注解需要加在测试类上
【2】利用java service机制引入
resources/META-INF/services目录下新建监听器配置,如果不存在目录自己新建
配置内容
myproj.annotation.MyAnnotationListener// 监听器路径
【3】在对应的xml文件中引入
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test name="Test">
<classes>
<class name="myproj.annotation.DemoTest"/>
</classes>
</test>
<listeners>
<listener class-name="myproj.annotation.MyAnnotationListener">自定义测试注解</listener>
</listeners>
</suite>