将自己的注释添加到 TestNG 中的动态跳过测试

Adding own annotation to dynamic skip test in TestNG

我想提供优雅的机制来在某些环境变量的值不可接受时跳过所选测试。我选择添加自己的注释 @RunCondition 来定义特定测试允许的值。然后我为 TestNG 创建了自己的侦听器,当环境变量的值不在注释参数中定义的允许范围内时,它将测试标记为禁用。

我的代码如下所示:

public class ExampleTest {

    private int envVar;

    @BeforeClass
    public void setUp() {
        //set up of some environmental variables which depends on external source
        StaticContext.setVar(getValueFromOuterSpace());
    }

    @RunCondition(envVar=2)
    @Test
    public void testFoo(){

    }
}


public class SkipTestTransformer implements IAnnotationTransformer {
    @Override
    public void transform(ITestAnnotation iTestAnnotation, Class aClass, Constructor constructor, Method method) {
        RunCondition annotation = method.getAnnotation(RunCondition.class);
        int[] admissibleValues = annotation.envVar();
        for (int val : admissibleValues) {
            if (StaticContext.getVar() == val) {
                return; // if environmental variable matches one of admissible values then do not skip
            }
        }
        iTestAnnotation.setEnabled(false);
    }
}

public @interface RunCondition {
    int[] envVar();
}

我的代码运行良好,但有一个小问题,即 transform 方法在 setUp 之前调用,即 @BeforeClass 函数。在所有测试初始化​​之后,运行 Transformer 是否还有其他可能性?我认为这样的解决方案优雅而清晰,我不希望任何丑陋的 if 子句达到我的目标...

我正在使用 Java 7 和 TestNG v5.11。

测试框架 直接支持一个更好的概念,称为假设。您不应该禁用测试,而应该跳过执行:

  • 在 JUnit 中,您可以使用 assumeThat(boolean) 系列方法
  • 在 TestNG 中你可以抛出 SkipException

在那种情况下该方法不会消失,它会被标记为已跳过。

尝试实现 IMethodInterceptor(此 class 的一个实例将在 TestNG 开始调用测试方法之前调用。)而不是注释转换器。它将允许管理将要执行的测试列表。它还允许使用您的测试注释。限制是具有依赖关系的测试方法不会传递给拦截方法。

您可以在设置方法 (@BeforeMethod) 中检查自己的注释并抛出 SkipException 以跳过此测试。

public class ExampleTest {

    private int envVar;

    @BeforeClass
    public void setUp() {
        //set up of some environmental variables which depends on external source
        StaticContext.setVar(2);
    }

    @BeforeMethod
    public void checkRunCondition(Method method) {
        RunCondition annotation = method.getAnnotation(RunCondition.class);
        if (annotation != null) {
            int[] admissibleValues = annotation.envVar();
            for (int val : admissibleValues) {
                if (StaticContext.getVar() == val) {
                    // if environmental variable matches one of admissible values then do not skip
                    throw new SkipException("skip because of RunCondition");
                }
            }
        }
    }

    @RunCondition(envVar = 2)
    @Test
    public void testFoo() {

    }

    @Retention(RetentionPolicy.RUNTIME)
    public @interface RunCondition {

        int[] envVar();
    }

}