Answers:
我们的目标是至少达到 70%。在更容易测试的事物上(例如功能数据结构),我们的目标是90%,大多数人的目标是尽可能接近100%。在与WPF相关的事情和其他很难测试的框架上,我们获得的覆盖率要低得多(只有70%)。
我认为仅代码覆盖率是一个很差的指标。例如,很容易产生大量无用的测试来覆盖代码,但是却没有充分检查输出或不测试边缘情况。覆盖代码只是意味着它不会引发异常,并非正确。您需要质量测试-数量不是那么重要。
“足够”是指您可以确信自己没有破坏任何东西的情况下可以对代码进行更改。在某些项目中,可能是10%,在其他项目中,可能是95%。
它几乎从未高达100%。但是,有时尝试获得100%的代码覆盖率可能是消除代码库中混乱的好方法。不要忘记,有两种方法可以增加代码覆盖率-编写更多测试或删除代码。如果由于难以测试而没有覆盖代码,则很有可能您可以简化或重构以使其更易于测试。如果它太晦涩难于进行测试,那么通常很有可能代码中没有其他东西正在使用它。
大多数代码中只有20%会在80%的时间运行。除非与调用图配对以确定最需要测试的内容,否则代码覆盖率分析不是很有用。这告诉您可能的情况。您可能只针对那些极端情况提出了100个测试,这些测试不到实际代码的5%。
因此,请确保覆盖定义关键路径的20%的100%,其余的至少50%(根据调用图)。这应该使您(大约)获得70%-75%的总覆盖率,但这有所不同。
不要浪费时间试图获得超过70%的总覆盖率,同时不对关键的情况进行检查。
我非常喜欢@RevBingo的回答,因为他建议100%的努力会导致您清理或删除未使用的代码。我在其他答案中没有看到的是一种何时需要高覆盖率以及何时不需要的感觉。我开始刺了一下。我认为,像这样向图表添加详细信息比找到一个适合所有代码的测试覆盖率编号更有用。
对于未连接到数据库且不返回HTML的公共API(例如java.util Collections),我认为100%的覆盖率是一个崇高的开始目标,即使您因时间或其他原因而选择90-95%约束。功能完备后,增加测试范围将比其他类型的代码审阅更详细地进行审查。如果您的API非常流行,人们将以您无法期望的方式使用它,对其进行子类化,反序列化等。您不希望他们的最初经验是发现错误或设计疏漏!
对于采用数据结构并返回数据结构的业务基础结构代码,100%可能仍然是一个不错的开始目标,但是,如果此代码的公开程度不足以引起很多误用,也许85%还是可以接受的?
对于接受并返回String的代码,我认为单元测试要脆弱得多,但是在许多情况下仍然有用。
我讨厌为返回HTML的函数编写测试,因为它是如此脆弱。如果有人更改了CSS,JavaScript或您返回的HTML和英语的全部内容,这对人类最终用户毫无意义?如果您可以找到一个使用大量业务逻辑来生成少量HTML的函数,则可能值得进行测试。但是相反的情况可能根本不值得测试。
对于某些代码,“正确”的定义是“对最终用户有意义”。您可以针对此代码执行非传统测试,例如自动语法检查或HTML验证输出。我什至设置了grep语句,以解决我们通常会在工作中遇到的一些小矛盾之处,例如在系统其余部分将其称为“登录”时说“登录”。这个人严格来说不是单元测试,而是在不期望特定输出的情况下捕获问题的有用方法。
但最终,只有人类才能判断对人类有意义的事物。单元测试无法帮助您。有时,需要几个人才能正确判断。
这是一个可悲的类别,我觉得不太适合写作。但是,在任何足够大的项目中,都会有很多漏洞,这些漏洞可能会占用人周的时间,却没有提供任何业务利益。
我买了一本书是因为它声称可以显示如何自动模拟数据以测试Hibernate。但是它仅测试了Hibernate HQL和SQL查询。如果必须执行大量的HQL和SQL,您实际上并没有获得Hibernate的优势。Hibernate内存数据库有一种形式,但是我还没有花时间来弄清楚如何在测试中有效地使用它。如果我运行了该程序,那么我希望对通过导航导致Hibernate运行某些查询的对象图来计算内容的任何业务逻辑进行较高的测试覆盖率(50%-100%)。我测试此代码的能力目前接近0%,这是一个问题。因此,我提高了项目其他区域的测试覆盖率,并尝试使用纯函数而不是访问数据库的函数,这主要是因为为这些函数编写测试更加容易。仍然,
我认为这取决于您正在测试的应用程序部分。例如,对于业务逻辑或涉及复杂数据转换的任何组件,我的目标是90%(尽可能高)的覆盖率。我经常通过测试尽可能多的代码来发现小而危险的错误。我宁愿在测试期间发现此类错误,也不要让它们在一年后出现在客户现场。同样,高代码覆盖率的好处在于,它可以防止人们过于轻易地更改工作代码,因为必须相应地调整测试。
另一方面,我认为有些组件的代码覆盖率不太合适。例如,在测试GUI时,编写一个测试以涵盖将单击按钮分配给正确的组件时单击的所有代码的测试非常耗时。我认为在这种情况下,使用传统的执行手动测试的方法会更加有效,您只需单击按钮并观察程序的行为即可(是否打开了正确的对话框窗口?是否选择了正确的工具? ?)。