0

true在学校作业中,我应该为返回参数 < 80 或其他情况的方法编写黑盒测试false。目前我的方法是

for (int i = 0; i < 80; i++) {
    assertTrue(someMethod(i));
}
for (int i = 80; i <= 100; i++) {
    assertFalse(someMethod(i));
}

但是,这将需要 100 个单独的断言。是否有最佳/更好的实践方法?如果相关,我正在使用 JUnit 5,但如果需要可以切换到 JUnit 4(毕竟这只是一个学校作业)。问候。

4

5 回答 5

1

对于 JUnit 5,请考虑重复测试功能:

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

对于您的情况,您可以重复 100 次:

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

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

我同意检查 1 - 100 不是完全必要的,只需检查 80 左右(79、80、81)。唯一可能值得的其他情况是检查负数,但在这种情况下,即使这样似乎也有些过分了。

如果您决定只检查 79,80,81 则ValueSource注释更清晰:

@ParameterizedTest
@ValueSource(ints = { 79, 80, 81 })
public void so(int argument)
{
   assertTrue((argument < 80) == someMethod(argument));
}
于 2018-12-03T15:52:45.383 回答
0

如果有人使用 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));
    }
} 
于 2018-12-04T09:46:00.627 回答
0

您可以做的(在 JUnit5 中)如下:

编写(至少)三个测试用例,涵盖三个主要用例,即输入< 80、输入> 80和输入= 80

它看起来像这样:

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

测试了这三个用例后,由于直接测试了边界以及最近的邻居,您可以确定所有剩余的数字。

于 2018-12-03T15:53:43.957 回答
0

您通常只需测试边缘情况就可以了,也许还有一个范围之一的额外代表,例如

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

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

在您的情况下,您可能还希望将截止值添加为常量(例如static final int THRESHOLD = 80)并在您的测试用例中使用它;这样,如果阈值发生变化,则更容易更改。

于 2018-12-03T15:42:10.493 回答
0

提到另一个选项 - 在这个简单的情况下 - 进行全方位检查:在 JUnit 5 平台上使用jqwik进行基于属性的测试:

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

如果你想真正看到完整的范围真的被生成了,@Report(Reporting.GENERATED)给属性方法添加注释,你会得到以下输出:

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

在 github 上找到完整的工作示例。

于 2018-12-05T13:56:11.973 回答