以前看他们的代码仅仅知道标签作用其他的都很模糊,直到看了一期视频才知道Testng有监听器这个接口,再回首看他们的代码瞬间看懂他们的结构,有种恍然大悟的感觉。还是得仔细研究啊,内容以后慢慢添加吧。
API https://testng.org/doc/index.html 发现把Document全部理解翻译就可以了,JavaDoc也很重要。
JavaDoc https://javadoc.jitpack.io/com/github/cbeust/testng/master/javadoc/overview-summary.html
谢谢以上作者
很不错的文章,详细解释各种监听器适用情况。
TestNG 监听器
大名鼎鼎的ITestNGListener监听器父类接口
Interface ITestNGListener
All Known Subinterfaces:
IAlterSuiteListener, IAnnotationTransformer, IAnnotationTransformer, IAnnotationTransformer2, IAnnotationTransformer3, IClassListener, IConfigurable, IConfigurationListener, IConfigurationListener2, IExecutionListener, IHookable, IInvokedMethodListener, IInvokedMethodListener2, IMethodInterceptor, IReporter, IResultListener, IResultListener2, ISuiteListener, ITestListener
All Known Implementing Classes:
DefaultAnnotationTransformer, DotTestListener, EmailableReporter, EmailableReporter2, ExitCodeListener, FailedReporter, JqReporter, JUnitReportReporter, JUnitXMLReporter, Main, SuiteHTMLReporter, SuiteRunner, TestHTMLReporter, TestListenerAdapter, TestNG.ExitCodeListener, TextReporter, VerboseReporter, XMLReporter
public interface ITestNGListener
This is a marker interface for all objects that can be passed as a -listener argument.
5.18 - TestNG Listeners
- IAnnotationTransformer,操作@Test标注
- IAnnotationTransformer2,操作@Configuration标注、@DataProvider标注和@Factory标注
- IAnnotationTransformer3,操作@Listeners标注
- IHookable
- IInvokedMethodListener
- IMethodInterceptor
- IReporter
- ISuiteListener
- ITestListene
可以通过以下方法调用监听器
- Using -listener on the command line.
- Using <listeners> with ant.
- Using <listeners> in your testng.xml file.
<suite>
<listeners>
<listener class-name="com.example.MyListener" />
<listener class-name="com.example.MyMethodInterceptor" />
</listeners>
- Using the @Listeners annotation on any of your test classes.
@Listeners({ com.example.MyListener.class, com.example.MyMethodInterceptor.class })
public class MyTest {
// ...
}
@Listeners可以注解任何继承于org.testng.ITestNGListener的类,除了IAnnotationTransformer 和IAnnotationTransformer2.原因是这些监听器需要在程序之前声明,因此TestNG才能重写注释。要想实现IAnnotationTransformer或 IAnnotationTransformer 2,需要将他们填写入testng.xml 文件中。
注意:@Listeners注释会应用于整个周期。等同于在Testng.xml 文件中声明他们。假如限制他们的作用域,比如仅仅在当前类中执行。
1.首先定义一个自定义注解来指定限制
@Retention(RetentionPolicy.RUNTIME)
@Target ({ElementType.TYPE})
public @interface DisableListener {}
2.在监听器中编辑
public void beforeInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) {
ConstructorOrMethod consOrMethod =iInvokedMethod.getTestMethod().getConstructorOrMethod();
DisableListener disable = consOrMethod.getMethod().getDeclaringClass().getAnnotation(DisableListener.class);
if (disable != null) {
return;
}
// else resume your normal operations
}
3. 在不想运行监听器的地方添加注解
@DisableListener
@Listeners({ com.example.MyListener.class, com.example.MyMethodInterceptor.class })
public class MyTest {
// ...
}
- Using ServiceLoader.
最后,JDK提供了一种通过 非常简练的机制来指定实现的接口 --ServiceLoader class. 可以在Jar文件中写入实现的监听器以及配置文件,然后把它放在classpath环境变量,这样TestNG可以自动找到它们。
转载:http://blog.csdn.net/wanghantong/article/details/40404939
这篇博客详细记载了ServiceLoader 使用方法。
例如,创建一个监听器。
package test.tmp;
public class TmpSuiteListener implements ISuiteListener {
@Override
public void onFinish(ISuite suite) {
System.out.println("Finishing");
}
@Override
public void onStart(ISuite suite) {
System.out.println("Starting");
}
}
编译这些文件,在META-INF/services/org.testng.ITestNGListener路径下创建一个文件。原文照搬。Compile this file, then create a file at the location META-INF/services/org.testng.ITestNGListener, which will name the implementation(s) you want for this interface.
You should end up with the following directory structure, with only two files:
$ tree
|____META-INF
| |____services
| | |____org.testng.ITestNGListener
|____test
| |____tmp
| | |____TmpSuiteListener.class
$ cat META-INF/services/org.testng.ITestNGListener
test.tmp.TmpSuiteListener
Create a jar of this directory:
$ jar cvf ../sl.jar .
added manifest
ignoring entry META-INF/
adding: META-INF/services/(in = 0) (out= 0)(stored 0%)
adding: META-INF/services/org.testng.ITestNGListener(in = 26) (out= 28)(deflated -7%)
adding: test/(in = 0) (out= 0)(stored 0%)
adding: test/tmp/(in = 0) (out= 0)(stored 0%)
adding: test/tmp/TmpSuiteListener.class(in = 849) (out= 470)(deflated 44%)
Next, put this jar file on your classpath when you invoke TestNG:
$ java -classpath sl.jar:testng.jar org.testng.TestNG testng-single.yaml
Starting
f2 11 2
PASSED: f2("2")
Finishing
This mechanism allows you to apply the same set of listeners to an entire organization just by adding a jar file to the classpath, instead of asking every single developer to remember to specify these listeners in their testng.xml file.
TestNG 监听接口详解
5.16 - Annotation Transformers
适用场景:允许在运行期间修改注解@XXX ,虽然注解在源代码中是不变的,但是在某种情况下会重写注解的值。,为了实现这种功能,称作Annotation Transformers
- IAnnotationTransformer,操作@Test标注
- IAnnotationTransformer2,操作@Configuration标注、@DataProvider标注和@Factory标注
- IAnnotationTransformer3,操作@Listeners标注
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);
}
同时也可以通过命令行以及ant指定类,或者以编程的方式。
java org.testng.TestNG -listener MyTransformer testng.xml
TestNG tng = new TestNG();
tng.setAnnotationTransformer(new MyTransformer());
// ...
一旦transfer()方法被调用,在TestNG进一步执行之前,可以调用ITest测试参数上的任何setter来更改其值。比如修改InvocationCount属性,
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 or @DataProvider), 使用 IAnnotationTransformer2代替。
5.21 - Overriding test methods
- IHookable
适用场景:覆盖或者跳过对测试方法的调用。尤其是需要测试方法需要一个指定的安全管理。(Java 认证和授权API)
// an example with JAAS
public class MyHook implements IHookable {
public void run(final IHookCallBack icb, ITestResult testResult) {
// Preferably initialized in a @Configuration method
mySubject = authenticateWithJAAs();
Subject.doAs(mySubject, new PrivilegedExceptionAction() {
public Object run() {
icb.callback(testResult);
}
};
}
}
5.17 - Method Interceptors
- IMethodInterceptor
适用场景:改变执行方法的顺序
public interface IMethodInterceptor {
List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context);
}
参数中传递的方法列表是可以以任何顺序运行的所有方法。您的拦截方法预计将返回类似的IMethodInstance列表,该列表可以是以下任意一种
- The same list you received in parameter but in a different order.
- A smaller list of IMethodInstance objects.
- A bigger list of IMethodInstance objects.
For example, here is a Method Interceptor that will reorder the methods so that test methods that belong to the group "fast" are always run first:
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;
}
6.2.1 - Logging Listeners
- ITestListene
ITestListener 实现类TestListenerAdapter
日志监听 Pass Fail 例子
public class DotTestListener extends TestListenerAdapter {
private int m_count = 0;
@Override
public void onTestFailure(ITestResult tr) {
log("F");
}
@Override
public void onTestSkipped(ITestResult tr) {
log("S");
}
@Override
public void onTestSuccess(ITestResult tr) {
log(".");
}
private void log(String string) {
System.out.print(string);
if (++m_count % 40 == 0) {
System.out.println("");
}
}
}
In this example, I chose to extend TestListenerAdapter, which implements ITestListener with empty methods, so I don't have to override other methods from the interface that I have no interest in. You can implement the interface directly if you prefer.
- IInvokedMethodListener
5.20 - Listening to method invocations
The listener IInvokedMethodListener allows you to be notified whenever TestNG is about to invoke a test (annotated with @Test) or configuration (annotated with any of the @Before or @After annotation) method. You need to implement the following interface:
public interface IInvokedMethodListener extends ITestNGListener {
void beforeInvocation(IInvokedMethod method, ITestResult testResult);
void afterInvocation(IInvokedMethod method, ITestResult testResult);
}
and declare it as a listener, as explained in the section about TestNG listeners.
- IReporter
The org.testng.IReporter interface only has one method:
public void generateReport(List<ISuite> suites, String outputDirectory)
This method will be invoked by TestNG when all the suites have been run and you can inspect its parameters to access all the information on the run that was just completed.
- ISuiteListener
- Method Summary
实现类:TestListenerAdapter
Class TestListenerAdapter
- java.lang.Object
-
- org.testng.TestListenerAdapter
-
All Implemented Interfaces:
IConfigurationListener, IConfigurationListener2, IResultListener, IResultListener2, ITestListener, ITestNGListener
Direct Known Subclasses:
DotTestListener, FailedReporter, TestHTMLReporter, TextReporter, VerboseReporter
public class TestListenerAdapter extends java.lang.Object implements IResultListener2
A simple ITestListener adapter that stores all the tests that were run. You can retrieve these results with the following methods: getPassedTests() getFailedTests() getSkippedTests() If you extend this class in order to override any of these methods, remember to call their super equivalent if you want this list of tests to be maintained.
-
Constructor Summary
Constructors Constructor and Description TestListenerAdapter()
-
Method Summary
Methods inherited from class java.lang.ObjectAll Methods Instance Methods Concrete Methods Modifier and Type Method and Description void
beforeConfiguration(ITestResult tr)
Invoked before a configuration method is invoked.
protected ITestNGMethod[]
getAllTestMethods()
java.util.List<ITestResult>
getConfigurationFailures()
java.util.List<ITestResult>
getConfigurationSkips()
java.util.List<ITestResult>
getFailedButWithinSuccessPercentageTests()
java.util.List<ITestResult>
getFailedTests()
java.util.List<ITestResult>
getPassedTests()
java.util.List<ITestResult>
getSkippedTests()
java.util.List<ITestContext>
getTestContexts()
void
onConfigurationFailure(ITestResult itr)
Invoked whenever a configuration method failed.
void
onConfigurationSkip(ITestResult itr)
Invoked whenever a configuration method was skipped.
void
onConfigurationSuccess(ITestResult itr)
Invoked whenever a configuration method succeeded.
void
onFinish(ITestContext testContext)
Invoked after all the tests have run and all their Configuration methods have been called.
void
onStart(ITestContext testContext)
Invoked after the test class is instantiated and before any configuration method is called.
void
onTestFailedButWithinSuccessPercentage(ITestResult tr)
Invoked each time a method fails but has been annotated with successPercentage and this failure still keeps it within the success percentage requested.
void
onTestFailure(ITestResult tr)
Invoked each time a test fails.
void
onTestSkipped(ITestResult tr)
Invoked each time a test is skipped.
void
onTestStart(ITestResult result)
Invoked each time before a test will be invoked.
void
onTestSuccess(ITestResult tr)
Invoked each time a test succeeds.
void
setAllTestMethods(java.util.List<ITestNGMethod> allTestMethods)
void
setFailedButWithinSuccessPercentageTests(java.util.List<ITestResult> failedButWithinSuccessPercentageTests)
void
setFailedTests(java.util.List<ITestResult> failedTests)
void
setPassedTests(java.util.List<ITestResult> passedTests)
void
setSkippedTests(java.util.List<ITestResult> skippedTests)
java.lang.String
toString()
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait