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

Junit Implement Execution condition for programatically disabling a test function

我正在尝试构建一个自定义注释以与 JUnit 测试一起使用 classes。 objective 是定期 运行 测试。

示例 class 到 运行: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,我们只想 运行 每隔(或每 2 次)测试一次。自定义注释如下所示:

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

最后 PeriodicEnabling 助手 class:

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

}

问题:

问题是在第一个测试函数的evaluateExecutionConditionreturnsEvaluationCondition.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 函数。但是我需要一些不同的东西,我需要一个自定义注释 class 来处理注释 class.

中每个测试函数的执行

感谢任何帮助:) !

您正在将扩展应用到 class,因此它不仅对各个方法有效,而且对 class 本身也是有效的。 Jupiter 然后尽职地调用 evaluateExecutionCondition 来确定 class 是否被禁用。既然如此,各个方法也将在没有进一步调用的情况下被禁用。

您的代码还有一些其他改进(例如,您不应该在扩展中包含字段)- 我建议阅读 JUnit 5 extension model(link 到 post 在我的博客上)。