如果我不太确定以下哪项测试是必要的或多余的。 考虑单元测试以下代码:
public class Locker {
public enum Type { FOO, BAR, FOOBAR };
private Locker() {}
public boolean shouldlock (int x) {
return x > 10;
}
public boolean lock (Type type, int x) {
switch (type) {
case FOO : return shouldlock(x);
case BAR : return shouldlock(x * 2);
}
return false;
}
}
测试用例1:测试shouldlock
的真假情况。 - 毫无疑问到目前为止。
Question 1
:
测试用例2:输入类型lock
的{{1}}也可以测试真假案例,即两者。 ?在其调用Foo
的基础上,我们已经测试了它的两种情况。因此,它可能是多余的。但不太确定。
shouldlock
:
测试案例3:假设对Question 2
的答案为真,我们是否还需要测试Question1
的真假案例?
Bar
:
测试案例4:假设对Question 3
的回答都是正确的。假设现在Question1 and Question2
被改为私有(假设它)。测试中唯一的区别是我应该省略shouldlock
吗?
Test case 1
:
测试用例5:是否需要检查唯一遗漏的枚举Question 4
是否返回错误?
FOOBAR
:
假设对问题4的回答是正确的,那么如果明天的枚举包含100多个项目怎么办?如何扩展这样的测试?
答案 0 :(得分:1)
首先,它取决于您的代码必须处理的场景。从这个角度来看,您可以考虑以测试驱动开发(TDD)方式处理您的工作,在该方式中,您首先编写应该涵盖所需功能的测试,然后编写使测试通过的代码。
通过这种方法,您的问题没有一般的有效答案。它只取决于你需要什么以及你需要多严谨。
其次,您可以考虑以下想法来进行单元测试:使单元测试代码覆盖率尽可能高。我在这里主要考虑的是行覆盖率和条件覆盖率。这意味着在单元测试期间执行的代码应该由尽可能多的行组成,并且它应该分别覆盖尽可能多的条件分支。
此外,通过这种方法,您可能希望尽可能地减少冗余,即保持行执行的次数尽可能低,但高于0(理想情况下为1)。在这种情况下,您的问题的答案是:
true
或false
。BAR
案例,但测试它(您希望涵盖case BAR
行。true
和false
个案例,就可以了。return false
行。答案 1 :(得分:1)
shouldlock
并验证是否使用x
调用它(可能使用测试的常量值)。使用类似Mockito之类的内容,只有在调用lock
时才会调用真实方法。shouldlock
调用了x * 2
验证。FOO
包含10和11,BAR
包含5和6。FOOBAR
进行一次测试。答案 2 :(得分:1)
我知道这是一个人为的例子,所以我会回答一下。
您希望使用尽可能多的输入进行测试,以确保代码正常工作。当然,您可能会错过一些东西,但是当您需要稍后重新创建该错误时,测试将会存在。
在shouldlock
的情况下,我会测试一组整数,让我放心,代码可以工作 - 比如一个非常低的负数,一个非常高的正数,0和更多有代表性的数字你期待作为输入。
至于lock
,你的问题表明你正在考虑实施,我认为这是一个错误。您需要根据方法的客户进行思考。具体来说,不要说“我们还需要测试BAR
吗?”相反,您只需要考虑一些合理数量的方法,客户可以调用您的方法并进行相应的测试。这意味着包含所有enum
值。
就规模而言,我认为这个问题没有实际意义,因为使用100项enum
进行测试的难度(尽管不太可能)表明您应该更改实现,因此您的方法可能会发生变化。那么你的测试就会反映出来。
至于将方法更改为private
,您不必再进行测试了。只需要测试您的公共API。您可能希望将断言添加到这些方法中。
底线是不要痛苦超过100%的测试覆盖率。收益递减,当发现错误时,您将有一个测试可以重现并修复它。