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

时间:2017-11-26 08:41:53

标签: java unit-testing junit naming-conventions junit5

我阅读了一些关于测试命名约定的文章,并决定使用" should"。它在大多数情况下都非常好用,例如:

  • shouldAccessDeniedIfWrongPassword
  • shouldReturnFizzBu​​zzIfDiv3And5
  • shouldIncreaseAccountWhenDeposit

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

Composer require "ZendFramework/ZendPdf":"2.0.2"

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

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

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

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

    @Test
    void shouldReturn11111111111111111111111111111111IfNumberNegative1() {
        decimal.setNumber(-1);
        assertEquals("11111111111111111111111111111111", decimal.toBinary());
    }

我认识到它因为惯例而过于复杂。万一我失败了,看起来会好得多:

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

我应该违反惯例以保持简单吗?与测试相同的命名问题,他们得到输入和输出或动态测试列表:

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

2 个答案:

答案 0 :(得分:3)

名称应该是有用的。有时规则有助于找到好名字,有时候,他们却没有。然后答案是放弃规则,也许可以选择完全不同的东西,例如:

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

如果你有这些方法中的几种,也许可以接受“ForMinus120”左右。

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

您不会使用许多几乎相似的测试方法 - 而是转向parameterized tests!含义:使用表格来推动测试。对于JUnit 5 和参数化测试,请转到here(感谢用户Sam Brannen)。

很高兴你花时间和精力让你的测试易于阅读。但在这种情况下,这会导致大量代码重复。相反,将输入/输出值放入,然后进行一次测试以检查该表中的所有条目。

答案 1 :(得分:0)

我在Roy Osherove's方法之后对我进行了建模,这是正则表达式

^(setup|teardown|([A-Z]{1}[0-9a-z]+)+_([A-Z0-9]+[0-9a-z]+)+_([A-Z0-9]+[0-9a-z]+)+)$