我正在使用TestNG框架,许多测试类扩展了Base抽象Test,提供了一些附加信息。
我想在整个测试类上设置@Test(启用=false)
,这在TestNG中是有问题的,因为方法上的任何@Test
注释都将覆盖第一个。这意味着,即使是禁用的类,所有方法都将运行。
我发现框架作者在拉取请求#816-添加侦听器中提供的解决方法,如果定义它们的类具有@Test(启用=false)
,则修改方法上的@Test
注释:
public class TestClassDisabler implements IAnnotationTransformer {
@Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor,
Method testMethod) {
if (testMethod != null) {
Test test = testMethod.getDeclaringClass().getAnnotation(Test.class);
if (test != null && !test.enabled()) {
annotation.setEnabled(false);
}
}
}
}
它像一个魅力一样工作,但仅适用于不使用继承的测试。对于这种情况,监听器的testMethod. getDeclaringClass()
返回声明方法的原始类,而不是启动方法的对象实例类。
@Test(enabled = false)
class SpecificTest extends BaseTest {
@Test
public void testSomething() {}
}
abstract class BaseTest {
@Test
public void veryGenericTest() {}
}
对于此示例,只有test东西
被禁用,veryGenericTest
仍然运行。
IAnnotationTransformer
在这里不是很好的选择。没有简单的方法可以获取调用方法的原始实例,只能基于Method
接口。我们只能获取声明方法的基类。
其他解决方案与ITherodInterceptor
一起工作,它允许在测试套件启动之前过滤掉方法并提供对测试类实例的访问。
public class TestMethodsDisabler implements IMethodInterceptor {
@Override
public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
List<IMethodInstance> testsToRun = new ArrayList<>();
for (IMethodInstance method : methods) {
Test testClass = method.getInstance()
.getClass()
.getAnnotation(Test.class);
if (testClass == null || testClass.enabled()) {
testsToRun.add(method);
}
}
return testsToRun;
}
}
这样,当我们在类上设置@Test(启用=false)
注释时,标准方法和继承方法都被禁用。
需要使用此拦截器在testng. xml
中创建测试套件:
<suite name="ListenersSuite" parallel="false">
<listeners>
<listener class-name="your.package.support.TestMethodsDisabler"/>
</listeners>
<test name="all-test" preserve-order="true" verbose="2">
<packages>
<package name="your.package.tests.*"/>
</packages>
</test>
</suite>
参考文献