我最近开始使用代码覆盖工具(特别是Emma和EclEmma),我真的很喜欢它让我了解单元测试的完整性 - 以及查看我的单元测试的代码区域的能力.一点儿打.我目前在一个没有进行大量单元测试的组织工作,我计划真正推动每个人进行单元测试和代码覆盖以及TDD,并希望转换组织.
我不确定这个问题的一个问题是我应该在多大程度上接受我的代码覆盖.例如,如果我有一个这样的类:
//this class is meant as a pseudo-enum - I'm stuck on Java 1.4 for time being public final class BillingUnit { public final static BillingUnit MONTH = new BillingUnit("month"); public final static BillingUnit YEAR = new BillingUnit("year"); private String value; private BillingUnit(String value) { this.value = value; } public String getValue() { return this.value; } public boolean equals(Object obj) { return value.equals(((BillingUnit) obj).getValue()); } public int hashCode() { return value.hashCode(); } }
我写了一些简单的单元测试,以确保equals()
正常工作,getValue()
返回我期望的等等.但由于EclEmma的视觉特性,该hashcode()
方法显示为"未测试"的亮红色.
hashCode()
在这个例子中,考虑实现有多简单,是否值得尝试进行测试?我觉得我会为这种方法添加一个单元测试,只是为了使代码覆盖率提高,并摆脱EclEmma添加到这些线上的明显红色突出显示.
也许我是神经质和类似OCD的,但我发现使用像EclEmma之类的东西可以很容易地看到未经测试的东西 - 插件突出显示红色的源代码,并覆盖绿色的代码 - 真的让我想要我尽可能多地获得100%绿色的课程 - 即使它没有增加太多的好处.
我使用代码覆盖来给出关于我可能有一组不完整测试的地方的提示.例如,我可能会为某些给定的功能编写一个测试,然后开发满足该功能的代码,但这样做实际上编写了比预期更多的代码 - 假设它可能在备用情况下捕获异常测试没有运动.当我使用覆盖率分析器时,我可以看到我引入了没有相关测试的代码.它帮助我知道我什么时候没有写足够的测试.
另一方面,覆盖率分析可能导致错误的安全性.覆盖所有代码并不意味着您有足够的测试.您需要从代码应该做什么的角度考虑测试并编写测试以确保它能够执行.优选通过首先编写测试.仅仅因为你的代码被完全覆盖并不意味着代码完成它应该做的事情.
在您的示例中,在编写代码之前,我会编写hashCode测试来定义方法的功能.因此,我会覆盖它.这并不意味着我总是有100%的报道.例如,我并不过分热衷于为简单的访问器编写测试.我也可能不会从我从框架继承的父类测试方法,因为我觉得不需要测试其他人的代码.
我认为使用一个库可以选择忽略某些类型的语句是值得的.例如,如果你有很多:
if(logger.isDebugEnabled()) { logger.debug("something"); }
如果您可以关闭这些行的覆盖率计算,这将非常有用.对于无关紧要的getter和setter(仅设置或返回成员变量而没有其他检查或副作用)的覆盖计算,也可以(可以说)有效.但我认为,如果你已经覆盖了equals和hashcode,那么应该对它们进行测试.您添加了非平凡的功能,应该进行测试.
需要明确的是,我认为上述情况应该从保险范围中排除的原因是:
没有测试该功能是否正常.您不必在整个测试套件中运行5次,将日志记录库设置为每个日志记录级别,以确保所有语句都被命中.
如果您执行了上述操作,则会以另一种方式扭曲您的保险范围.如果90%的分支机构是if(log.isDebugEnabled())
,你测试他们所有,但没有其他分支,它看起来就像你有90%的分支覆盖率(好),在现实中,你有0%不平凡的分支覆盖(糟糕!) .