我最近开始使用代码复盖率的工具(特别是艾玛和EclEmma),我真的很喜欢的图,它给我的完整性的我的单元测试和能力来看看有什么区域的代码我的单元的测试没有击中。我目前的工作中一个组织,不做了很多单元的测试,并且我计划在真正推动每个人都需要对单元的测试和代码复盖率和文字,希望转换的组织。

一个问题,我不确定这个问题是究竟如何,到目前为止,我应该把我的代码复盖范围。例如,如果我有一类,如:

//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增加了这些行。

也许我太神经质和强迫症状,但我发现,使用什么样的EclEmma,使得它很容易看到了什么是未经测试的-插件突出了源代码红色代码复盖在绿色的-真的让我想要推动让尽可能多的类100%的绿色作为我可以的-即使它不会增加多少益处。

有帮助吗?

解决方案

我使用代码覆盖率给出了我可能有一组不完整测试的地方的提示。例如,我可能会为某些给定的功能编写一个测试,然后开发满足该功能的代码,但这样做实际上编写了比预期更多的代码 - 假设它可能在备用情况下捕获异常测试没有运动。当我使用覆盖率分析器时,我可以看到我引入了没有相关测试的代码。它帮助我知道我什么时候没有编写足够的测试。

另一方面,覆盖率分析可能导致错误的安全性。覆盖所有代码并不意味着您有足够的测试。您需要从代码应该做什么的角度考虑测试并编写测试以确保它能够执行。优选通过首先编写测试。仅仅因为你的代码被完全覆盖并不意味着代码完成它应该做的事情。

在您的示例中,我会在编写代码之前为hashCode编写测试以定义方法的功能。因此,我会覆盖它。这并不意味着我总是有100%的报道。例如,我并不过分热衷于为简单的访问器编写测试。我也可能不会从父类中测试我从框架继承的方法,因为我觉得不需要测试其他人的代码。

其他提示

我认为这是值得用一个图书馆,在那里你可以选择忽略某些种类的声明。例如,如果你有很多:

if(logger.isDebugEnabled()) {
    logger.debug("something");
}

它是有用的,如果你可以关闭的复盖范围的计算对于那些各种各样的线路。它还可以(可以说)有效关闭复盖率的计算用于琐碎的吸气,并制定者(那些简单的设置或返回的一个成员变量没有任何其他检查或侧面的影响)。然而,我认为,如果你有复盖平等和哈希码,那些应该进行测试。你加入非微不足道的功能,并应当进行测试。

只是为了澄清,其原因我认为上述情况应被排除在复盖范围是:

  • 不测试这一功能是确定。你不应该跑过你的整套测试的5倍,与伐木图书馆设置为每个日志记录的水平,只是为了确保所有发言的打击。
  • 如果你有以上,这将歪曲您的复盖范围的其他办法。如果90%的树枝 if(log.isDebugEnabled()), 和你的试验他们所有,但没有任何其他分支机构,它看起来就像你有90%的支的复盖范围(良好),当在现实中,你有0%的非微不足道的分支的复盖面(不好!!).

代码覆盖率和测试覆盖率之间存在差异。您应该尝试确保您的代码经过充分测试,而不是100%的代码覆盖率。

请考虑以下代码:

public float reciprocal (float ex)
{
    return (1.0 / ex) ;
}

如果您运行了一个传递值为1.0的测试,那么您将获得所有传递的100%代码覆盖率(分支和语句)。代码显然有缺陷。

测量测试覆盖率更加困难,而且来自成为更好的开发人员和测试人员。

具体来说,对于hashCode,一个凶手会说你应该对该方法进行单独的单元测试。我个人会确保它包含在至少一个单元集成测试中,并且不会直接测试每个访问器/修改器。您的投资回报通常太低,无法证明这一努力。这当然假设你有一个单元测试,确保你生成正确的哈希码。

达到100%的复盖代码 有意义的 测试可能不值得爬上,并且,如前所述,100%的复盖代码并不一定意味着所有可能的条件应用程序已经过测试。

至于测试 equals, hashCode 和一些其他的 合同的基础 接口,就像 ComparableSerializable, 我不包括那些测试。这是很重要的 equals/hashCode 合同是正确实施,同样有 equals/Comparable.

看看 JUnit-插件, 尤其是

现在可能不会太复杂,但如果方法被修改,稍后检查以确认它仍然按预期工作可能会非常有用。

由于检查应该很容易编写,为什么不这样做呢?它可以帮助统计数据,也可以帮助您稍后检查,以防它破裂。

此外,对于TDD,您希望100%覆盖,因为您可以确定(或非常接近它)您在重构时没有破坏任何内容。

一位同事程序员在旧的Java1.4中像我一样陷入困境;)

正如我的之前所述回答,所涵盖的代码未经过代码测试。结论是:从某一点来看,改善代码覆盖率的唯一方法是......删除代码!

现在,关于hashCode,有趣的是它在单元测试设计中被覆盖以检查预期的排序机制是否被尊重(而不是用于覆盖另一个函数)

正如我在其他地方所说的那样,低代码覆盖率是一个问题,但高代码覆盖率并不意味着你正在编写纯金。

如果你不关心代码覆盖率,那么我建议你需要测试 equals() getValue() - 取决于如何以及在哪里使用 hashCode()(抱歉,我是C#开发人员),那么可能想要测试它。

最重要的部分是,您的测试可以让您确信您已编写正确的代码,并且代码可以按预期工作。

在这种特殊情况下,我会说,既然你正在测试equals方法,你也可以测试相等的对象是否具有相同的哈希码:只需对所有等于预期返回true的情况添加一个额外的测试

这将为您提供代码覆盖率,并且在讨价还价中它会让您对hashCode实际满足其合同有信心: - )

鉴于你显然可以信任String的hashCode方法,并且你不希望永远改变这个类,这只是勉强值得的。但是如果你对你的equals方法有足够的怀疑来测试它,那么你应该怀疑它是否可以测试它和hashCode保持一致。而且你应该始终怀疑你以后不会想要弄乱你以前做过的假设。例如,如果某人出现并决定通过添加指针等式检查来“优化”,那么您也可以为他们提供一套完整的测试来运行修改后的代码。否则他们会把时间浪费在同样的担心上 - 我没有代码覆盖吗?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top