第一步,引入testng依赖
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.10</version>
</dependency>
第二步,创建自定义注解,定义所需字段
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
public String name() default "";
public int id() default 0;
}
第三步,创建注解对应的Listener
实现 IInvokedMethodListener 接口中的两个方法
// 在测试类中每一个方法执行前先执行一次 void beforeInvocation(IInvokedMethod var1, ITestResult var2); // 在测试类中每一个方法执行后都执行一次 void afterInvocation(IInvokedMethod var1, ITestResult var2);
每个方法执行前都会执行一遍beforeInvocation、afterInvocation,比如在测试类中增加before、after、setUp、tearDown方法,执行后都会调用,测试代码
public class DemoTest {
@BeforeMethod
public void before(){
System.out.println("before...");
}
@AfterMethod
public void after(){
System.out.println("after...");
}
@BeforeClass
public void setUp(){
System.out.println("setUp...");
}
@AfterClass
public void tearDown(){
System.out.println("tearDown...");
}
@MyAnnotation(id=1,name = "ZhangSan")
@Test
public void gg(){
}
}
测试结果见下图(左图测试中中添加了before、after等方法,可以看到每次调用前都会调一遍,右图只有一个测试方法)
具体代码实现如下:
package myproj.annotation;
import org.testng.*;
public class MyAnnotationListener implements IInvokedMethodListener, ITestListener {
private int id;
private String name;
private boolean testSuccess = true;
@Override
public void beforeInvocation(IInvokedMethod method, ITestResult result) {
System.out.println("====beforeInvocation====");
if (method.isTestMethod()&&annotationPresent(method,MyAnnotation.class)){
System.out.println("beforeInvocation...");
System.out.println("Name: "+name+" id: "+id);
System.out.println(result.toString());
}
}
@Override
public void afterInvocation(IInvokedMethod method, ITestResult result) {
System.out.println("====afterInvocation====");
if (method.isTestMethod()&&method.getClass().isAnnotationPresent(MyAnnotation.class)){
System.out.println(" invoked afterAnnotation");
}
if (!testSuccess){
result.setStatus(ITestResult.FAILURE);
}
}
@Override
public void onTestStart(ITestResult iTestResult) {
System.out.println("====onTestStart====");
System.out.println("onTestStart"+iTestResult);
}
@Override
public void onTestSuccess(ITestResult iTestResult) {
System.out.println("====onTestSuccess====");
System.out.println("onTestSuccess"+iTestResult);
}
@Override
public void onTestFailure(ITestResult iTestResult) {
System.out.println("====onTestFailure====");
System.out.println("onTestFailure"+iTestResult);
}
@Override
public void onTestSkipped(ITestResult iTestResult) {
System.out.println("====onTestSkipped====");
System.out.println("onTestFailure"+iTestResult);
}
@Override
public void onTestFailedButWithinSuccessPercentage(ITestResult iTestResult) {
System.out.println("====onTestFailedButWithinSuccessPercentage====");
}
@Override
public void onStart(ITestContext context) {
System.out.println("====onStart====");
for (ITestNGMethod m1:context.getAllTestMethods()
) {
if (m1.getConstructorOrMethod().getMethod().isAnnotationPresent(MyAnnotation.class)){
name=m1.getConstructorOrMethod().getMethod().getAnnotation(MyAnnotation.class).name();
id=m1.getConstructorOrMethod().getMethod().getAnnotation(MyAnnotation.class).id();
}
}
}
@Override
public void onFinish(ITestContext iTestContext) {
System.out.println("====onFinish====");
}
private boolean annotationPresent(IInvokedMethod method,Class<MyAnnotation> clazz){
return method.getTestMethod().getConstructorOrMethod().getMethod().isAnnotationPresent(clazz);
}
第四步,引入Listener
【1】直接在测试类中引入,Listener注解需要加在测试类上
@Listeners(myproj.annotation.MyAnnotationListener.class)// 直接引入
public class DemoTest {
@MyAnnotation(id=1,name = "ZhangSan")
@Test
public void gg(){
}
}
输出
[TestNG] Running:
/Users/mtdp1/Library/Caches/IntelliJIdea2019.1/temp-testng-customsuite.xml
====onStart====
====onStart====
====onTestStart====
onTestStart[TestResult name=gg status=STARTED method=DemoTest.gg()[pri:0, instance:myproj.annotation.DemoTest@685cb137] output={null}]
====onTestStart====
onTestStart[TestResult name=gg status=STARTED method=DemoTest.gg()[pri:0, instance:myproj.annotation.DemoTest@685cb137] output={null}]
====beforeInvocation====
beforeInvocation...
Name: ZhangSan id: 1
[TestResult name=gg status=STARTED method=DemoTest.gg()[pri:0, instance:myproj.annotation.DemoTest@685cb137] output={null}]
====afterInvocation====
====onTestSuccess====
onTestSuccess[TestResult name=gg status=SUCCESS method=DemoTest.gg()[pri:0, instance:myproj.annotation.DemoTest@685cb137] output={null}]
====onTestSuccess====
onTestSuccess[TestResult name=gg status=SUCCESS method=DemoTest.gg()[pri:0, instance:myproj.annotation.DemoTest@685cb137] output={null}]
====onFinish====
====onFinish====
===============================================
Default Suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
【2】更多监听器使用方法参考:TestNG监听器https://blog.csdn.net/wan_zaiyunduan/article/details/123757483