在大多数的例子中,TestNG提供的注解能满足我们的需求,但是有时候你会想自己写一个注解去满足一些想要的东东。
那么如何自己创建一个自己的注解呢?
请紧跟下面的步骤:
1. 创建一个maven项目,并引入TestNG依赖
2. 创建你的注解
3. 创建注解对应的Listener
4. 引入Listener(选任意一种)
引入Listener有多种方法,下面主要讲三种
a. 在你的测试类中加上
@Listeners(com.testng.annotation.MyAnnotationListener.class)
public class TestMyAnnotationListener {...}
b. 在你的测试类中加上testng.xml里添加
<listeners>
<listener class-name="com.testng.annotation.MyAnnotationListener"></listener>
</listeners>
c. 使用java services机制注入
在/src/main/resources下创建一个叫org.testng.ITestNGListener的文件,并把你的Listener Class的全路径放入进去,如: com.testng.annotation.MyAnnotationListener
下面是代码:
注解:
package com.testng.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
public String name() default "";
public int id();
}
注解对应的Listener:
package com.testng.annotation;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
public class MyAnnotationListener implements IInvokedMethodListener, ITestListener {
private int id;
private String name;
private boolean testSuccess = true;
public void onTestStart(ITestResult result) {
System.out.println("onTestStart" + result);
}
public void onTestSuccess(ITestResult result) {
System.out.println("onTestSuccess" + result);
}
public void onTestFailure(ITestResult result) {
System.out.println("onTestFailure"+ result);
}
public void onTestSkipped(ITestResult result) {
System.out.println("onTestSkipped"+ result);
}
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
System.out.println("onTestFailedButWithinSuccessPercentage" + result);
}
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();
}
}
}
public void onFinish(ITestContext context) {
System.out.println("onFinish");
}
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
System.out.println("beforeInvocation");
if(method.isTestMethod() && annotationPresent(method, MyAnnotation.class) ) {
System.out.println("beforeAnnotation...");
System.out.println("Name: " + name + " Id: " + id);
System.out.println(testResult.toString());
}
}
private boolean annotationPresent(IInvokedMethod method, Class<MyAnnotation> clazz) {
return method.getTestMethod().getConstructorOrMethod().getMethod().isAnnotationPresent(clazz) ? true : false;
}
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
System.out.println("afterInvocation");
if(method.isTestMethod()) {
if(method.getClass().isAnnotationPresent(MyAnnotation.class)) {
System.out.println("invoked afterAnnotation");
}
if( !testSuccess ) {
testResult.setStatus(ITestResult.FAILURE);
}
}
}
}
测试类:
package com.testng.annotation;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
//@Listeners(com.testng.annotation.MyAnnotationListener.class)
public class TestMyAnnotationListener {
@MyAnnotation(id = 1, name="Matt")
@Test
public void testMyAnnotationListener(){
System.out.println("testMyAnnotationListener>>>>>");
}
}
testng.xml
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1" >
<listeners>
<listener class-name="com.testng.annotation.MyAnnotationListener"></listener>
</listeners>
<test name="test" >
<packages>
<package name="com.testng.annotation" />
</packages>
</test>
</suite>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.testng.annotation</groupId>
<artifactId>com.testng.annotation</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.6</version>
</dependency>
</dependencies>
</project>
运行结果:
[TestNG] Running:
/Users/matt/Desktop/workspace/com.testng.annotation/testng.xml
onStart
onTestStart[TestResult name=testMyAnnotationListener status=STARTED method=TestMyAnnotationListener.testMyAnnotationListener()[pri:0, instance:com.testng.annotation.TestMyAnnotationListener@6ad5c04e] output={null}]
beforeInvocation
beforeAnnotation...
Name: Matt Id: 1
[TestResult name=testMyAnnotationListener status=STARTED method=TestMyAnnotationListener.testMyAnnotationListener()[pri:0, instance:com.testng.annotation.TestMyAnnotationListener@6ad5c04e] output={null}]
testMyAnnotationListener>>>>>
afterInvocation
onTestSuccess[TestResult name=testMyAnnotationListener status=SUCCESS method=TestMyAnnotationListener.testMyAnnotationListener()[pri:0, instance:com.testng.annotation.TestMyAnnotationListener@6ad5c04e] output={null}]
onFinish
===============================================
Suite1
Total tests run: 1, Failures: 0, Skips: 0
===============================================
参考资料:
Testng官方网档:http://testng.org/doc/documentation-main.html
TestNg @Listener的使用: http://topmanopensource.iteye.com/blog/1983035
TestNg 监听器: http://blog.csdn.net/wanghantong/article/details/40404939
create your own testng annotation: http://amareshp.github.io/Creating-Your-Own-TestNG-Annotation/