Best practice for looped JUnit test

耗尽温柔 提交于 2019-12-04 21:41:20

For JUnit 5 consider the repeated test feature:

https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests

For your case you could repeat 100 times:

@ParameterizedTest
@MethodSource("args")
public void so(int argument)
{
   assertTrue((argument < 80) == someMethod(argument));
}

private static IntStream args()
{
   return IntStream.range(0, 100);
}

I would agree checking 1 - 100 is not totally necessary, just check around 80 (79, 80, 81). The only other case that might be worthwhile is checking a negative number but even that seems overkill in this case.

If you do decide to just check 79,80,81 then the ValueSource annotation is cleaner:

@ParameterizedTest
@ValueSource(ints = { 79, 80, 81 })
public void so(int argument)
{
   assertTrue((argument < 80) == someMethod(argument));
}

You'd usually be fine with just testing the edge cases, and maybe one additional representative of one of the ranges, eg

assertTrue(someMethod(79));
assertFalse(someMethod(80));

// not reaaaally necessary
assertTrue(someMethod(50));
assertFalse(someMethod(100));

In your case, you might also want to add the cutoff as a constant (eg static final int THRESHOLD = 80) and use it in your test cases; this way it's easier to change if the threshold changes.

What you could do (in JUnit5) is the following:

Write (at least) three test cases that cover the three main use cases, those are an input < 80, an input > 80 and the input = 80.

It would be looking like this:

@Test
@DisplayName("[< 80]")
@Tag("below_eighty")
void numberBelowEightyTest(TestInfo testInfo) {
    int number = 79;
    assertTrue(someMethod(number));
}

@Test
@DisplayName("[= 80]")
@Tag("equals_eighty")
void numberEqualsEightyTest(TestInfo testInfo) {
    int number = 80;
    assertFalse(someMethod(number));
}

@Test
@DisplayName("[> 80]")
@Tag("above_eighty")
void numberAboveEightyTest(TestInfo testInfo) {
    int number = 81;
    assertFalse(someMethod(number));
}

Having tested those three use cases, you can be sure for all remaining numbers due to having tested the border directly as well as the nearest neighbours.

In case someone using JUnit 4:

@RunWith(Parameterized.class)
public class PerformanceStatusTest {

    @Parameterized.Parameters
    public static List<Integer> data() {
        return IntStream.range(0, 100)
                .boxed()
                .collect(Collectors.toList());
    }

    private int testValue;

    public PerformanceStatusTest(final int testValue) {
        this.testValue = testValue;
    }

    @Test
    public void someMethodTest() {
        assertTrue((testValue < 80) == someMethod(testValue));
    }
} 

To mention another option which will - in this simple case - do full range checking: Use property-based testing with jqwik on the JUnit 5 platform:

import org.junit.jupiter.api.*;

import net.jqwik.api.*;
import net.jqwik.api.constraints.*;

class PartitionedFunctionProperty {

    @Property
    void below80returnTrue(@ForAll @IntRange(min= 0, max = 79) int aNumber) {
        Assertions.assertTrue(someMethod(aNumber));
    }

    @Property
    void from80returnFalse(@ForAll @IntRange(min = 80, max = 100) int aNumber) {
        Assertions.assertFalse(someMethod(aNumber));
    }

    private boolean someMethod(int aNumber) {
        if (aNumber < 80) return true;
        return false;
    }
}

If you want to really see that the full range is really being generated, add annotation @Report(Reporting.GENERATED) to the property method and you'll get the following output:

timestamp = 2018-12-05T14:50:36.668, generated = [80]
timestamp = 2018-12-05T14:50:36.671, generated = [81]
timestamp = 2018-12-05T14:50:36.672, generated = [82]
timestamp = 2018-12-05T14:50:36.672, generated = [83]
...
timestamp = 2018-12-05T14:50:36.676, generated = [98]
timestamp = 2018-12-05T14:50:36.676, generated = [99]
timestamp = 2018-12-05T14:50:36.677, generated = [100]

timestamp = 2018-12-05T14:50:36.679
    tries = 21
    checks = 21
    generation-mode = EXHAUSTIVE
    after-failure = SAMPLE_ONLY
    seed = 4490524914178941008

Find the full working example on github.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!