Java 分组测试的单元测试名称约定
我读了一些关于测试命名约定的文章,并决定将其与“应该”一起使用。它在大多数情况下都非常有效,例如:Java 分组测试的单元测试名称约定,java,unit-testing,junit,naming-conventions,junit5,Java,Unit Testing,Junit,Naming Conventions,Junit5,我读了一些关于测试命名约定的文章,并决定将其与“应该”一起使用。它在大多数情况下都非常有效,例如: 应该访问DenieDfWrong密码 应该返回FizzBuzzIfDiv3和5 存款时应增加账户 但我在测试在不同数字系统中显示数字的小数表示类时遇到了问题,请看代码: public class DecimalRepresentationTest { private DecimalRepresentation decimal; @BeforeEach void se
- 应该访问DenieDfWrong密码
- 应该返回FizzBuzzIfDiv3和5
- 存款时应增加账户
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());}
);
}
我是否应该打破传统,保持简单?与我在测试中遇到的命名问题相同,它们会得到带有输入和输出或动态测试的列表:
@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());
}));
}
@TestFactory
流应该返回GoodResultsforPositionEnumbers(){//查看方法名lol
列表输入=新的ArrayList(Arrays.asList(2,15));
列表输出=新的ArrayList(Arrays.asList(“10”、“1111”);
返回inputs.stream().map(number->DynamicTest.DynamicTest(“测试阳性”+number,()->{
int idx=输入。indexOf(数字);
decimal.setNumber(inputs.get(idx));
assertEquals(outputs.get(idx)、decimal.toBinary());
}));
}
名字应该是有用的。有时规则有助于找到好名字,有时则不然。然后,答案是放弃规则,也许去做一些完全不同的事情,比如:
@Test
void testResultForNegativeInput() {
decimal.setNumber(-120);
assertEquals("11111111111111111111111110001000", decimal.toBinary());
}
如果你有几个这样的方法,也许加上“ForMinus120”左右是可以接受的
但是不要在这里花费精力命名:真正的问题是你使用了错误的测试类型:你有一大堆输入数据,这只会导致不同的输出值需要检查。所有的测试都是关于:一个特殊的输入值应该导致一个特殊的输出值
你不会用许多几乎相似的测试方法来做这件事,相反,你会求助于!意思:使用表格来驱动您的测试。对于JUnit5和参数化测试,请转向(感谢用户)
你花时间和精力使你的测试容易阅读,这是很好的。但在这种情况下,这会导致大量代码重复。相反,将输入/输出值放入一个表中,并进行一次测试以检查该表中的所有条目。名称应该是有用的。有时规则有助于找到好名字,有时则不然。然后,答案是放弃规则,也许去做一些完全不同的事情,比如:
@Test
void testResultForNegativeInput() {
decimal.setNumber(-120);
assertEquals("11111111111111111111111110001000", decimal.toBinary());
}
如果你有几个这样的方法,也许加上“ForMinus120”左右是可以接受的
但是不要在这里花费精力命名:真正的问题是你使用了错误的测试类型:你有一大堆输入数据,这只会导致不同的输出值需要检查。所有的测试都是关于:一个特殊的输入值应该导致一个特殊的输出值
你不会用许多几乎相似的测试方法来做这件事,相反,你会求助于!意思:使用表格来驱动您的测试。对于JUnit5和参数化测试,请转向(感谢用户)
你花时间和精力使你的测试容易阅读,这是很好的。但在这种情况下,这会导致大量代码重复。相反,将输入/输出值放入一个表中,并进行one测试以检查该表中的所有条目。我已经按照我的方法建模,下面是正则表达式
^(setup | teardown |([A-Z]{1}[0-9a-Z]+)+([A-Z0-9]+[0-9a-Z]+([A-Z0-9]+[0-9a-Z]+)$
我已经在方法之后建模了,这里是正则表达式
^(setup | teardown |([A-Z]{1}[0-9a-Z]+)+([A-Z0-9]+[0-9a-Z]+([A-Z0-9]+[0-9a-Z]+)$
我不会为确切的结果命名测试用例。您所做的只是复制测试用例的实现。可以将其称为shouldReturnedExpectedValueForminUnisone
,或者其他任何名称。因此,如果有多个断言,shouldReturnedExpectedValuesfornegativeNumber可以吗?当然可以。我的意思是,说“应该做预期的事情”有点多余,因为根据定义,测试测试它正在做你期望的事情;但这比说“我希望它做的事情是XXX,我希望它做XXX”要好,这就是你通过把结果写在名字里所做的。好吧,非常感谢:)我知道,我很固执,但我投了赞成票,只是为了表示我对你花时间思考这些事情的感谢。我不会为确切的结果命名测试用例。您所做的只是复制测试用例的实现。可以将其称为shouldReturnedExpectedValueForminUnisone
,或者其他任何名称。因此,如果有多个断言,shouldReturnedExpectedValuesfornegativeNumber可以吗?当然可以。我的意思是,说“应该做预期的事情”有点多余,因为根据定义,测试测试它正在做你期望的事情;但这总比说“我希望它做的事情是XXX,我希望它做XXX”要好,这就是你把结果写在名字里所做的。好吧,非常感谢:)我知道,我很固执,但我投了赞成票,只是为了表示我感谢你花时间思考这些事情。这是否意味着对象[0][0]是输入,对象[0][1]期望值?依此类推,对象[1][0]输入、对象[1][1]预期值等?该表包含每次测试所需的数据。所以,是的-一个表行将包含-120和相应的预期字符串值。非常感谢:)仅供参考:OP询问了JUnit 5(即JUnit Jupiter)。因此,参数化测试支持的链接应该指向这里。@minizibi这是一个不同的主题。请考虑问一个新问题。牢记这