TestNG学习-beanshell、注解转换和方法拦截器

简介: TestNG学习-beanshell、注解转换和方法拦截器

1. BeanShell和高级组选择

   如果testng.xml中的<include>和<exclude>标记不足以满足需要,则可以使用BeanShell表达式来确定是否应在测试运行中包含某种测试方法。可以在<test>标记下指定此表达式:

<test name="BeanShell test">
   <method-selectors>
     <method-selector>
       <script language="beanshell"><![CDATA[
         groups.containsKey("test1")
       ]]></script>
     </method-selector>
   </method-selectors>
  <!-- ... -->

   当在testng.xml中找到<script>标记时,TestNG将忽略当前<test>标记中随后的组和方法的<include>和<exclude>:BeanShell表达式将唯一决定一个测试方法是否包含在内。

   有关BeanShell脚本的一些其他信息:

  • 返回值必须返回一个布尔值。除此之外,允许使用任何有效的BeanShell代码(例如,你可能希望在工作日返回true,而在周末返回false,这将允许你根据日期以不同的方式运行测试)。
  • 为了方便起见,TestNG定义了以下变量:
  • java.lang.reflect.Method方法:当前的测试方法。
  • org.testng.ITestNGMethod testngMethod:当前测试方法的描述。
  • java.util.Map <String,String> groups:当前测试方法所属的组的映射。
  • 通过用CDATA声明包围表达式(如上所示),以避免冗长的保留XML字符引用。


2. 注解的转换

   TestNG允许您在运行时修改所有注解的内容。 通常的使用情况是:注解大多数时候无需修改,仅在在某些需要的情况下,需要覆盖它们的值。为了实现这个目的,需要使用注解转换器(Annotation Transformer)。

   Annotation Transformer是一个实现以下接口的类:

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);
}

   与所有其他TestNG监听器一样,您可以在命令行或使用ant来指定这个类:

java org.testng.TestNG -listener MyTransformer testng.xml

   或者以编码的形式指定:

TestNG tng = new TestNG();
tng.setAnnotationTransformer(new MyTransformer());
// ...

   调用方法transform()时,可以在TestNG进程运行之前,调用ITest测试参数上的任何设置方法来更改其值。

   以下面的示例说明,示例是如何重写属性invocationCount的方法,在仅调用其中一个测试类的invoke()方法的情况下:

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或@DataProvider等),需要使用IAnnotationTransformer2。


3. 方法拦截器

   一旦TestNG计算了测试方法将被调用的顺序,这些方法将分为两组:

  • 按顺序运行的方法。这些都是具有依赖项或依赖项的测试方法。这些方法将以特定顺序运行。
  • 没有特定的运行顺序的方法。这些都是不属于第一类的方法。这些测试方法的运行顺序是随机的,一次运行到下一次运行可能会有所不同(尽管默认情况下,TestNG会尝试按类对测试方法进行分组)。

   为了能够更好地控制属于第二类的方法,TestNG定义了以下接口:

public interface IMethodInterceptor {
  List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context);
}

   传入的方法列表参数是可以按任何顺序运行的所有方法。预期的拦截方法将返回类似的IMethodInstance列表,该列表可以是以下任意一种:

  • 与传入参数的方法列表相同,但顺序不同。
  • 比IMethodInstance列表规模小一些的方法列表。
  • 比IMethodInstance列表规模大一些的方法列表。

   定义拦截器后,将其作为监听器传递给TestNG。例如:

java -classpath "testng-jdk15.jar:test/build" org.testng.TestNG -listener test.methodinterceptors.NullMethodInterceptor
   -testclass test.methodinterceptors.FooTest

   一个方法拦截器示例,它将对方法进行重新排序,始终首先运行属于“快速”组的测试方法:

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;
}

 放假放假了,欢迎关注交流~

相关文章
|
2月前
|
Java Spring 容器
[JavaWeb]——过滤器filter与拦截器Interceptor的使用、执行过程、区别
[JavaWeb]——过滤器filter与拦截器Interceptor的使用、执行过程、区别
|
8月前
|
Java
【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤(三)
【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤(三)
41 0
|
8月前
|
Java
SpringBoot 如何使用 @ExceptionHandler 注解进行局部异常处理
SpringBoot 如何使用 @ExceptionHandler 注解进行局部异常处理
|
5月前
|
SQL Java 数据库连接
干翻Mybatis源码系列之第十一篇:Mybatis拦截器获取被拦截对象的方法和参数
干翻Mybatis源码系列之第十一篇:Mybatis拦截器获取被拦截对象的方法和参数
|
8月前
|
JSON 前端开发 Java
【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤(一)
【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤
55 0
|
8月前
|
JSON Java 测试技术
【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤(二)
【SpringMVC】注解、参数传递、返回值和页面跳转的关键步骤(二)
46 0
|
9月前
|
监控 Java 数据库连接
深入解析Java中的MyBatis Plus注解 @InterceptorIgnore:优雅控制拦截器行为
拦截器是在数据库操作过程中执行的一种功能扩展机制,可以用于实现数据过滤、性能监控等功能。MyBatis Plus作为一款优秀的ORM框架,提供了注解 `@InterceptorIgnore`,使开发者能够更加灵活地控制拦截器的行为,从而实现更细粒度的拦截。本文将详细介绍 `@InterceptorIgnore` 注解的用法及其在持久层开发中的应用。
4109 0
|
9月前
|
Java 数据库连接 数据库
深入了解Java中的MyBatis Plus注解 @FieldStrategy:灵活处理字段策略
在数据库操作中,对于字段的操作可能需要根据不同的业务需求,采取不同的处理策略,比如插入操作时某些字段需要强制设值,更新操作时某些字段需要忽略等。MyBatis Plus作为一款强大的ORM框架,提供了注解 `@FieldStrategy`,使开发者能够更加灵活地处理字段的操作策略,从而减少代码的重复和冗余。本文将详细介绍 `@FieldStrategy` 注解的用法及其在持久层开发中的应用。
663 0
|
12月前
|
缓存 监控 前端开发
Java Web开发中过滤器,拦截器和监听器的区别
Java Web开发中过滤器,拦截器和监听器的区别
57 0
|
Java Spring 容器
SpringBoot中添加拦截器,在拦截器中注入其他类的时候出现空指针异常解决办法
SpringBoot中添加拦截器,在拦截器中注入其他类的时候出现空指针异常解决办法
327 0