< 100%测试覆盖率 - 选择测试区域的最佳实践

时间:2010-04-09 17:28:58

标签: testing

假设您正在处理项目,而时间/金钱预算不允许100%覆盖所有代码/路径。

然后,需要测试代码的一些关键子集。显然,可以使用“肠道检查”方法来测试系统,直觉和手动分析可以产生某种“确定”的测试覆盖范围。

但是,我假设有最佳实践/方法/流程可以识别关键元素达到某个阈值,并让您将测试元素集中在这些块上。

例如,一种识别制造失败的流行过程是失效模式和效果分析。我正在寻找一个过程来识别软件中的关键测试块。

8 个答案:

答案 0 :(得分:11)

100%的代码覆盖率不是理想的目标。由于某些原因,请参阅this blog

我的最佳做法是从用例中派生测试用例。在您的系统应该实现的用例和证明它有效的测试用例之间创建具体的可跟踪性(我使用UML工具但电子表也可以)。

明确识别最关键的用例。现在看看他们追踪的测试用例。您是否有许多针对关键用例的测试用例?它们是否涵盖了用例的所有方面?它们是否涵盖了消极和例外情况?

我发现这是确保良好报道的最佳公式(并最好地利用团队的时间)。

编辑:

为什么100%代码覆盖率不保证您测试100%案例的简单,人为的示例。假设CriticalProcess()应该调用AppendFile()来追加文本,而是调用WriteFile()来覆盖文本。

[UnitTest]
Cover100Percent()
{
    CriticalProcess(true, false);
    Assert(FileContents("TestFile.txt") == "A is true");

    CriticalProcess(false, true);
    Assert(FileContents("TestFile.txt") == "B is true");

    // You could leave out this test, have 100% code coverage, and not know
    // the app is broken.
    CriticalProcess(true, true);
    Assert(FileContents("TestFile.txt") == "A is trueB is true");
}

void CriticalProcess(bool a, bool b)
{
    if (a)
    {
        WriteFile("TestFile.txt", "A is true");
    }

    if (b)
    {
        WriteFile("TestFile.txt", "B is true");
    }
}

答案 1 :(得分:5)

除非您使用TDD进行绿地开发,否则您不太可能获得(或想要)100%的测试覆盖率。代码覆盖范围更像是一个指导原则,可以问“我没有测试过什么?”

您可能希望查看其他指标,例如cyclomatic complexity。找到代码的复杂区域并测试它们(然后重构以简化)。

答案 2 :(得分:3)

您应该注意3个主要组件:

  • 重要功能 - 您应该知道什么更重要。问问自己“”如果这个组件/代码片段中存在错误,我(或我的客户)会有多么紧张?“。您的客户可能会帮助您确定这些优先级。直接涉及金钱的事情往往会随之而来这个案例
  • 常用功能 - 最常见的用例应该尽可能没有错误。如果系统的一部分中没有人使用
  • ,则没有人关心
  • 最复杂的功能 - 开发人员通常很清楚代码的哪些部分更容易包含错误。你应该特别注意那些。

如果你有这个信息,那么选择如何分发测试资源可能并不难。

答案 3 :(得分:3)

虚假的安全感:您应该始终意识到测试覆盖率会误导虚假的安全感。关于这一事实的伟大文章可以在the disco blog中找到。这就是说依靠“绿色”指标的信息可以让你错过未经测试的路径。

未经测试的路径的良好指标另一方面,大多数时间以红色显示缺少测试覆盖率始终是未覆盖路径的一个很好的指标。您可以先查看这些内容,因为它们很容易识别,并允许您评估是否要在此处添加测试覆盖率。

以代码为中心的方法来识别关键元素:有一个很好的工具支持可以帮助您找到代码中的混乱和可能的陷阱。您可能希望查看IntelliJ IDE及其代码分析功能,或者查看Findbugs,Checkstyle和PMD。结合这些免费提供的静态代码分析工具的一个很棒的工具是Sonar

以功能为中心的approch来识别关键元素:评估您的软件并将其细分为功能。问自己这样的问题:“哪些功能最重要,哪些功能最可靠?我们在哪里必须注意结果的正确性?哪些错误或失败会对软件造成最大的破坏?”

答案 4 :(得分:2)

可能最好的暗示模块未被充分覆盖的是针对它的错误报告。你一次又一次编辑的任何模块都应该被很好地覆盖。但是圈复杂性与bug频率相关性很好 - 你可以在出现错误之前测量

答案 5 :(得分:2)

如果你有一个遗留的代码库,一个好的起点是:

  • 为您找到并修复的每个错误添加单元测试。单元测试应该重现错误,然后你修复代码,并使用单元测试来验证它是否已修复,然后确保将来它不会因任何原因再次中断。

  • 在可能的情况下,将测试添加到主要的高级组件,以便许多低级别的破坏仍然会导致单元测试失败(例如,不是单独测试每个数据库访问例程,添加一个创建数据库的测试,添加100个用户,删除其中的50个,验证结果并删除数据库。您将不会轻易看到 where 失败(您必须调试以解决失败的原因)但至少你知道你有一个测试来运行整个数据库系统,如果代码的那个区域出现任何重大问题,你会很快发出警告。一旦你有更高级别的领域,你可以担心深入研究。

  • 为新代码添加单元测试,或修改任何代码。

随着时间的推移,这本身将帮助您在更重要的地方建立覆盖范围。

(请记住,如果您的代码库工作的代码已经运行多年,那么在大多数情况下,您不需要“单元测试”来证明它是有效的。如果您只是将单元测试添加到所有内容中,它们几乎全部通过,因此不会告诉你太多。当然,随着时间的推移,你可能会开始检测这些测试中的回归,你会发现在以前未经测试的情况下添加单元测试的过程中的错误代码,但如果你只是盲目地通过代码盲目地为所有内容添加单元测试,那么你将得到一个非常差的每个bug修复比例的成本)

答案 6 :(得分:1)

这完全取决于您正在开发的软件类型。如果可以远程访问,那么安全性测试应该是最高优先级。对于Web应用程序,可以使用Sitewatch或Wapiti等自动化测试。还有一些工具可以帮助生成SOAP的单元测试。

答案 7 :(得分:1)

对所有90%覆盖率测试者:

这样做的问题是,10%难以测试的代码也是包含90%错误的重要代码!这是经过多年TDD后我凭经验得出的结论。

毕竟这是非常简单的结论。这10%难以测试的代码很难测试因为它反映了棘手的业务问题或棘手的设计缺陷或两者兼而有之。这些确切的原因通常会导致错误的代码。

但是:

  • 100%覆盖的代码随着时间的推移而减少到低于100%,通常会指出错误或至少是一个缺陷。
  • 与合同一起使用的100%覆盖代码,是实现接近无错代码的终极武器。 Code Contracts and Automated Testing are pretty much the same thing
  • 如果在100%覆盖的代码中发现错误,则更容易修复。由于测试已经涵盖了负责该错误的代码,因此编写新测试来解决错误修复并不困难。