Junit实现执行条件,以编程方式禁用测试功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Junit实现执行条件,以编程方式禁用测试功能相关的知识,希望对你有一定的参考价值。

我正在尝试构建一个与JUnit测试类一起使用的自定义注释。目标是定期运行测试。

要运行的示例类:TempTest.java

  @Periodic(period = 2)
  public class TempTest {
    @Test
    @ExtendWith(PeriodicEnabling.class)
    public void testTrue() {
        assertTrue(true);
    }

    @Test
    @ExtendWith(PeriodicEnabling.class)
    public void testZero() {
        int val = 0; assertEquals(0, val);
    }

    @Test
    @ExtendWith(PeriodicEnabling.class)
    public void testZero2() {
        assertEquals(0, "".length());
    }

    @Test
    @ExtendWith(PeriodicEnabling.class)
    public void testFalse() {
        assertTrue(!false);
    }
 }

因此,对于period = 2,我们只希望每隔一次(或每次第二次)测试。自定义注释如下所示:

@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(PeriodicEnabling.class)
@Target(ElementType.TYPE)
public @interface Periodic {
    int period() default 1;
}

最后是PeriodicEnabling助手类:

public class PeriodicEnabling implements ExecutionCondition {
    private int period, currCount;

    private static final ConditionEvaluationResult ENABLED = ConditionEvaluationResult.enabled("Count looks good!");
    private static final ConditionEvaluationResult DISABLED = ConditionEvaluationResult.disabled("Disabled due to periodic disabling!");

    public PeriodicEnabling() {
        System.out.println("Constructor!!");

        Class<TempTest> cls = TempTest.class;

        if(cls.isAnnotationPresent(Periodic.class)) {
            Annotation annotation = cls.getAnnotation(Periodic.class);
            this.period = ((Periodic) annotation).period();
        } else {
            this.period = 1;
        }

        currCount = 0;
    }

    @Override
    public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext extensionContext) {
        System.out.println("before::currCount = " + currCount);

        currCount++;

        int result = this.currCount % this.period;

        if (result == 0) {
            System.out.println("after::enabled::currCount = " + currCount);
            return ENABLED;
        }

        System.out.println("after::disabled::currCount = " + currCount + ", result=" + result);
        return DISABLED;
    }

}

问题:

问题是在第一个测试函数的evaluateExecutionCondition返回EvaluationCondition.Disabled之后,其余函数不再为它们执行evaluateExecutionCondition函数。其余的测试用例根本不运行。

这是我在运行示例测试文件时看到的输出:

Constructor!! 

before::currCount = 0
after::disabled::currCount = 1, result=1

Disabled due to periodic disabling!

Disabled due to periodic disabling!

Disabled due to periodic disabling!

Disabled due to periodic disabling!

我看到了一些解决方案,其中解决方案是使用assumeThat函数,其中包含一些动态条件。但是我需要一些不同的东西,我需要一个自定义的注释类来处理带注释的类中每个测试函数的执行。

任何帮助表示赞赏:)!

答案

您正在将扩展应用于类,因此它不仅对单个方法有效,而且对类本身也有效。木星然后尽职尽责地调用evaluateExecutionCondition来确定该类是否被禁用。由于它是,所以在没有进一步调用的情况下也禁用各个方法。

您的代码中还有其他一些改进(例如,您不应该在扩展中添加字段) - 我建议您阅读JUnit 5 extension model上的内容(链接到我博客上的帖子)。

以上是关于Junit实现执行条件,以编程方式禁用测试功能的主要内容,如果未能解决你的问题,请参考以下文章

Selenium - 以编程方式将 html 转换为 junit

以编程方式禁用android中的触摸输入

JUnit VS TestNG

在 Junit 4 中运行所有测试

在不创建上下文的情况下禁用 Spring 和 Junit5 测试

Junit @Rule如何运作?