如果项目具有100%的单元测试覆盖率,是否仍需要集成测试?

时间:2009-02-17 15:37:41

标签: unit-testing

如果项目有100%的单元测试覆盖率,是否还需要集成测试?

我从未参与过具有100%单元测试覆盖率的项目,但我想知道您的项目是否获得此项目(或90%),您的体验是否仍需要集成测试? (你需要更少吗?)

我问,因为集成测试似乎很糟糕。它们通常是缓慢的,脆弱的(容易折断),不透明(当有人不得不潜入所有层以找出问题时),并且导致我们的项目放慢速度......我开始认为拥有只有单元测试(也许是一小部分烟雾测试)才是最佳选择。

从长远来看,集成测试(根据我的经验)似乎比他们节省的成本更高。

感谢您的考虑。

13 个答案:

答案 0 :(得分:16)

解释

我认为在讨论之前定义你的条款很重要。

单元测试单独测试单个单元。对我来说,那是一堂课。单元测试将创建一个对象,调用方法并检查结果。它回答了“我的代码是否符合我的意图吗?”这个问题。

集成测试测试系统中两个组件的组合。它侧重于组件之间的关系,而不是组件本身。它回答了“将这些组件按预期一起工作”的问题。

系统测试测试整个软件系统。它回答了“这个软件是否按预期工作?”的问题。

验收测试是一种自动化的方式,让客户回答“这个软件我认为我想要的是什么?”。这是一种系统测试。

请注意,这些测试都没有回答诸如“这个软件有用吗?”之类的问题。或“这个软件易于使用吗?”。

所有自动化测试都受公理限制“端到端比你想象的更远” - 最终人类不得不坐在电脑前看着你的用户界面。 / p>

比较

单元测试更快,更容易编写,运行更快,更容易诊断。它们不依赖于“外部”元素,如文件系统或数据库,因此它们更简单/更快/更可靠。大多数单元测试在重构时继续工作(良好的单元测试是安全重构的唯一方法)。他们绝对要求你的代码解耦,这很难,除非你先写测试。这些因素的组合使得TDD的Red / Green / Refactor序列运行良好。

系统测试很难编写,因为它们必须经过如此多的设置才能达到您想要测试的特定情况。它们很脆弱,因为之前软件行为的任何变化都会影响导致您要测试的情况的顺序,即使该行为与测试无关。出于类似的原因,它们比单元测试慢得多。故障可能非常难以诊断,因为它可能需要很长时间才能到达故障点,并且因为故障涉及太多软件。在某些软件中,系统测试很难实现自动化。

集成测试介于两者之间:它们比系统测试更容易编写,运行和诊断,但覆盖范围比单元测试更广。

建议

结合使用测试策略来平衡每种策略的成本和价值。

答案 1 :(得分:15)

即使所有“单位”都做了他们应该做的事情,也不能保证整个系统按设计工作。

答案 2 :(得分:4)

是的,此外还有一些不同类型的代码覆盖率

from wiki:

  • 功能覆盖率 - 程序中的每个功能是否已执行?
  • 声明范围 - 是否已执行源代码的每一行?
  • 决策覆盖率(也称为分支覆盖率) - 每个控制结构(例如if语句)是否都被评估为true和false?
  • 条件覆盖率 - 每个布尔子表达式都被评估为true和false(这不一定意味着决策覆盖)?
  • 修改后的条件/决策覆盖范围(MC / DC) - 决策中的每个条件是否至少对所有可能的结果进行了一次?是否已证明每种情况都会独立影响该决策结果?
  • 路径覆盖 - 是否已执行代码中给定部分的所有可能路由?
  • 进入/退出保险范围 - 是否已执行所有可能的呼叫并返回该功能?

路径覆盖率,例如,因为每个方法都被调用,并不意味着如果按给定顺序调用各种方法,则不会发生错误。

答案 3 :(得分:2)

首先,即使在单元测试级别,100%的单元测试覆盖率还不够:您只能覆盖代码的100%指令。你的代码中的路径怎么样?输入或输出域怎么样?

其次,您不知道发送方单元的输出是否与其接收方单元的输入兼容。这是集成测试的目的。

最后,单元测试可以在与生产不同的环境中进行。集成测试可能会发现差异。

答案 4 :(得分:2)

您只能使用测试/覆盖证明存在错误,但您永远无法使用测试/覆盖证明代码没有错误。这一事实表明了测试/覆盖的界限。这在数学中是相同的,你可以通过找到一个反例来反驳一个定理,但你永远不能通过找不到反例来证明一个定理。因此,测试和覆盖仅仅是正确性证明的替代品,这些证据难以完成,因此几乎从未使用过。测试和覆盖可以提高代码的质量,但不能保证。它仍然是一门工艺而非科学。

答案 5 :(得分:2)

我还没有真正看到涵盖这些考虑因素的答案。现在,我从整体系统的角度讲,不是形成SW发展的视角,而是... 集成基本上是将较低级别的产品组合成更高级别产品的过程。每个级别都有自己的要求,以符合要求。尽管某些要求可能相同,但不同级别的总体要求集将有所不同。这意味着测试目标在不同级别上是不同的。 此外,较高级别产品的环境环境往往与较低级别产品的环境不同(例如,SW模块测试可能发生在桌面环境中,而完整的可加载SW项目可能在加载到其HW组件中时进行测试)。 此外,较低级别的组件开发人员可能对更高级别的产品开发人员的需求和设计没有相同的理解,因此集成测试也在一定程度上验证了较低级别的产品开发。

答案 6 :(得分:1)

单元测试与集成测试不同。

只是为了说明一点:如果我必须选择,我会转储单元测试并进行集成测试。经验告诉我们,单元测试有助于确保功能,并在开发周期的早期发现错误。

集成测试是在产品看起来与最终用户看起来很接近的情况下完成的。这也很重要。

答案 7 :(得分:1)

单元测试通常都是关于单独测试你的类。它们应该被设计成确保给定特定输入,您的班级表现出可预测和预期的行为。

集成测试通常都是关于彼此组合测试您的类以及使用这些类的“外部”程序。他们应该专注于确保当整个产品使用您的类时,它是以正确的方式这样做。

答案 8 :(得分:1)

“不透明(当有人必须潜入所有层以找出问题时)” - 这正是集成测试完成的原因 - 否则这些不透明的问题会出现在生产环境中。

答案 9 :(得分:0)

是的,因为您的软件功能取决于它的不同部分如何互动。单元测试取决于您使用输入并定义预期输出。这样做并不能保证它可以与系统的其余部分一起使用。

是的,当您引入故意更改输出的代码更改时,集成测试很难处理。通过我们的软件,我们通过专注于将集成测试的保存结果与保存的正确结果进行比较来最小化。

我们有一个工具可以在我们确定产生正确结果时使用。它会加载旧的已保存的正确结果并修改它们以使用新的设置。

答案 10 :(得分:0)

我经常看到良好的集成测试发现的各种问题 - 特别是如果你可以自动化一些集成测试。

单元测试非常棒,但您可以在单元测试中实现100%的代码覆盖率而不会有100%的相关性。你真的想尝试不同的东西,对吧?在单元测试中,您通常会寻找特定函数的边缘情况,而集成测试会在所有这些函数交互时向您展示更高级别的问题。

如果您在软件中构建API,则可以将其用于自动集成测试 - 过去我已经获得了很多好处。我不知道我会说我倾向于单元测试以支持集成测试,但是当它们做得正确时,它们是一个非常强大的附加功能。

答案 11 :(得分:0)

This exact question基本上只是在一天前被问过。有关可能遇到的大量错误,请参阅this question,即使是100%的代码覆盖率。

答案 12 :(得分:0)

它看起来不像这里提到的那样,但你实际上永远不会有100%的单元测试覆盖率(如果你有一个数据库)。在为数据库连接和CRUD操作编写单元测试的那一刻,您刚刚创建了一个集成测试。原因是因为您的测试现在具有独立于各个工作单元之外的依赖性。我所参与的项目以及我与之交谈过的开发人员一直表示剩余的10%是DAO或服务层。测试的最佳方法是使用集成测试和模拟(内存)数据库。我已经看到尝试模拟连接以便对DAO进行单元测试,但我并没有真正看到这一点 - 您的DAO只是一种将原始数据从一种格式序列化到另一种格式的方式,您的经理或代表将决定如何操纵它。