在TestNG中为动态跳过测试添加自己的注释

时间:2015-01-29 21:37:22

标签: java 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吗?我认为这样的解决方案优雅而清晰,我不想要任何丑陋的条款达到我的目标......

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

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

您可以在设置方法(@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();
    }

}