TestNg 监听器

以前看他们的代码仅仅知道标签作用其他的都很模糊,直到看了一期视频才知道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提供的几种监听器

IReport接口

Testng失败的用例重跑

TestNG自定义监听器大全

谢谢以上作者

很不错的文章,详细解释各种监听器适用情况。


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
    • All Methods Instance Methods Abstract Methods
      Modifier and TypeMethod and Description
      voidonFinish(ISuite suite)

      This method is invoked after the SuiteRunner has run all the test suites.

      voidonStart(ISuite suite)

      This method is invoked before the SuiteRunner starts.


实现类:TestListenerAdapter

Class TestListenerAdapter

  • java.lang.Object
    • org.testng.TestListenerAdapter
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值