jeudi 4 octobre 2018

Junit Implement Execution condition for programatically disabling a test function

I am trying to build a custom annotation to be used along with JUnit test classes. The objective is to periodically run tests.

Example class to run: 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);
    }
 }

So with period = 2 we want to only run every other (or 2nd) test. The custom annotation looks like this:

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

And finally the PeriodicEnabling helper 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;
    }

}


Problem:

The problem is after the first test function's evaluateExecutionCondition returns EvaluationCondition.Disabled, the rest of the functions do not execute the evaluateExecutionCondition function again for them. The rest of the test cases do not run at all.

Here's the output I see when I run the example test file:

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!


I saw some solution where the solution was to use the assumeThat function with some dynamic condition within it. But I need something different, I need a custom annotation class to handle the execution of every test function in the annotated class.

Any help is appreciated :) !

Aucun commentaire:

Enregistrer un commentaire