分组测试的单元测试名称约定

min*_*ibi 2 java junit unit-testing naming-conventions junit5

我读了一些关于测试命名约定的文章,并决定使用带有“should”的文章。它在大多数情况下都工作得很好,例如:

  • 如果密码错误则应访问被拒绝
  • shouldReturnFizzBu​​zzIfDiv3And5
  • 存款时应该增加账户

但是我在测试 DecimalRepresentation 类时遇到了问题,该类显示不同数字系统中的数字,只需查看代码:

public class DecimalRepresentationTest {

    private DecimalRepresentation decimal;

    @BeforeEach
    void setup() {
        decimal = new DecimalRepresentation();
    }

    @Test
    void shouldReturnZeroIfNumberNotSpecified() {
        assertEquals("0", decimal.toBinary());
    }

    @Test
    void shouldReturn10IfNumber2() {
        decimal.setNumber(2);
        assertEquals("10", decimal.toBinary());
    }

    @Test
    void shouldReturn1111IfNumber15() {
        decimal.setNumber(15);
        assertEquals("1111", decimal.toBinary());
    }
}
Run Code Online (Sandbox Code Playgroud)

现在还不错,但如果我测试负输入,它看起来很糟糕:

    @Test
    void shouldReturn11111111111111111111111110001000IfNumberNegative120() {
        decimal.setNumber(-120);
        assertEquals("11111111111111111111111110001000", decimal.toBinary());
    }

    @Test
    void shouldReturn11111111111111111111111111111111IfNumberNegative1() {
        decimal.setNumber(-1);
        assertEquals("11111111111111111111111111111111", decimal.toBinary());
    }
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,我对正输入和负输入进行了两次测试,以确保没有硬编码结果并且算法工作正常,因此我决定将测试分组到嵌套类中以保持约定:

@Nested
@DisplayName("Tests for positive numbers")
class PositiveConverter {
    @Test
    void shouldReturn10IfNumber2() {
        decimal.setNumber(2);
        assertEquals("10", decimal.toBinary());
    }

    @Test
    void shouldReturn1111IfNumber15() {
        decimal.setNumber(15);
        assertEquals("1111", decimal.toBinary());

    }
}

@Nested
@DisplayName("Tests for negative numbers")
class NegativeConverter {
    @Test
    void shouldReturn11111111111111111111111110001000IfNumberNegative120() {
        decimal.setNumber(-120);
        assertEquals("11111111111111111111111110001000", decimal.toBinary());
    }

    @Test
    void shouldReturn11111111111111111111111111111111IfNumberNegative1() {
        decimal.setNumber(-1);
        assertEquals("11111111111111111111111111111111", decimal.toBinary());
    }
}
Run Code Online (Sandbox Code Playgroud)

我意识到由于惯例,它过于复杂。万一我失误了,它看起来会好得多:

@Test
void testPositiveConversions() {
    assertAll(
            () -> {decimal.setNumber(2); assertEquals("10", decimal.toBinary());},
            () -> {decimal.setNumber(15); assertEquals("1111", decimal.toBinary());}
    );
}

@Test
void testNegativeConversions() {
    assertAll(
            () -> {decimal.setNumber(-120); assertEquals("11111111111111111111111110001000", decimal.toBinary());},
            () -> {decimal.setNumber(-1); assertEquals("11111111111111111111111111111111", decimal.toBinary());}
    );
} 
Run Code Online (Sandbox Code Playgroud)

我应该打破惯例以保持简单吗?我在测试中遇到同样的命名问题,他们得到带有输入和输出或动态测试的列表:

@TestFactory
Stream<DynamicTest> shouldReturnGoodResultsForPositiveNumbers(){ // look at method name lol
    List<Integer> inputs = new ArrayList<>(Arrays.asList(2, 15));
    List<String> outputs = new ArrayList<>(Arrays.asList("10", "1111"));

    return inputs.stream().map(number -> DynamicTest.dynamicTest("Test positive " + number, () -> {
        int idx = inputs.indexOf(number);
        decimal.setNumber(inputs.get(idx));
        assertEquals(outputs.get(idx), decimal.toBinary());
    }));
}
Run Code Online (Sandbox Code Playgroud)

Gho*_*ica 5

名字应该是有帮助的。有时规则有助于找到好名字,有时则不然。然后答案就是放弃规则,也许采取完全不同的东西,比如:

@Test
void testResultForNegativeInput() {
  decimal.setNumber(-120);
  assertEquals("11111111111111111111111110001000", decimal.toBinary());
 }
Run Code Online (Sandbox Code Playgroud)

如果您有多个这样的方法,也许添加“ForMinus120”左右是可以接受的。

但与其在这里花费精力命名:真正的问题是您使用了错误的测试类型:您有一大堆输入数据,这只会导致需要检查的不同输出值。您所有的测试都是关于:一个特殊的输入值应该导致一个特殊的输出值。

您不会使用许多几乎相似的测试方法来做到这一点 - 相反,您转向参数化测试!含义:使用表格来驱动测试。对于 JUnit 5和参数化测试,请转到此处(感谢用户Sam Brannen)。

您花费时间和精力使您的测试易于阅读,这真是太好了。但在这种情况下,这会导致大量代码重复。相反,将输入/输出值放入一张中,并进行一个测试来检查该表中的所有条目。

  • 仅供参考:OP 询问了 JUnit 5(即 JUnit Jupiter)。因此,参数化测试支持的链接应指向此处的[参数化测试](http://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests)。 (3认同)