模拟框架和高测试覆盖率是否重要?

时间:2009-10-21 16:14:31

标签: frameworks mocking easymock

模拟框架,例如EasyMock,可以更轻松地插入虚拟依赖项。话虽如此,使用它们来确保如何调用特定组件的不同方法(以及以何种顺序)对我来说似乎很糟糕。它将行为暴露给测试类,这使得维护生产代码变得更加困难。我真的没有看到好处;在精神上,我觉得我被锁在一个沉重的球上。

我更愿意只针对接口进行测试,将测试数据作为输入并断言结果。更好的是,使用一些自动生成测试数据的测试工具来验证给定的属性。例如将一个元素添加到列表中,并立即将其删除会产生相同的列表。

在我们的工作场所,我们使用Hudson进行测试覆盖。不幸的是,它很容易盲目地痴迷于所有东西都经过测试。我强烈认为,如果想要在维护模式下保持高效,我不应该测试所有内容。一个很好的例子是Web框架中的控制器。通常它们应该包含非常少的逻辑,使用控制器调用的模拟框架进行测试,并且这种方法在特定顺序中是不诚实的。

亲爱的SOers,您对此有何看法?

5 个答案:

答案 0 :(得分:3)

我读了两个问题:

您对以特定顺序调用组件上的特定方法有何看法?

我过去曾犯过这种罪行。这些天我们使用了更多的“存根”而不是“嘲弄”。 我们尝试编写仅测试一件事的单元测试。当我们这样做时,通常可以编写一个非常简单的测试,其中存在缺陷 与大多数其他组件的交互。我们很少断言订购。这有助于使测试不那么脆弱。

只测试一件事的测试更容易理解和维护。

此外,如果您发现自己不得不为与大量组件的交互写下很多期望,那么您正在测试的代码中可能存在问题。如果维护测试很困难,那么您正在测试的代码通常可以重构。

是否应该痴迷于测试覆盖率?

在为特定课程编写单元测试时,我非常痴迷于测试覆盖率。它使我很容易发现我没有测试过的重要行为。我也可以判断一下我不需要涉及哪些比特。

整体单元测试覆盖率统计数据?只要它们很高,就不会特别感兴趣。

整个系统的100%单元测试覆盖率?对此毫无兴趣。

答案 1 :(得分:2)

我同意 - 我赞成严重依赖于状态验证,而不是行为验证(对classical TDD的宽松解释,同时仍然使用测试双打)。

这本书The Art of Unit Testing在这些领域有很多好的建议。

100%的测试覆盖率,GUI测试,测试getter / setter或其他无逻辑代码等似乎不太可能提供良好的ROI。 TDD将在任何情况下提供高测试覆盖率。测试可能会破坏的东西。

答案 2 :(得分:1)

我问了一个类似的问题How Much Unit Testing is a Good Thing,这可能有助于了解人们认为合适的各种测试级别。

答案 3 :(得分:1)

  1. 在代码维护期间,一些初级员工会破坏运行“控制器调用此类方法以及特定顺序”的代码部分的概率是多少?

  2. 如果发生这样的事情,您的组织会有多少成本 - 生产中断,调试/修复/重新测试/重新发布,法律/财务风险,声誉风险等......?

  3. 现在,将#1和#2相乘,检查您是否不愿意达到合理数量的测试覆盖率是值得冒险的。

    有时,它不会(这就是为什么在测试中有一个收益递减点的概念)。

    E.g。如果您维护一个非生产关键的Web应用程序,并且有100个用户在应用程序损坏时(和/或可以轻松立即回滚)有解决方法,那么花3个月对该应用程序进行全面测试覆盖可能是非-sensical。

    如果你在一个应用程序上工作,其中一个小错误可能会产生数百万美元或更糟糕的后果(想想航天飞机软件,或巡航导弹的导航系统),那么全面覆盖的全面测试会变得更加敏感

    另外,我不确定我是否正在阅读你的问题,但你似乎暗示具有模拟功能的单元测试会以某种方式排除应用程序/集成功能测试。如果是这种情况,你反对这样一个概念是正确的 - 两种测试方法必须共存。

答案 4 :(得分:1)

这取决于您对程序域的建模方式。

如果根据存储在数据结构中的数据和从一个数据结构读取数据的方法对域进行建模,并将派生数据存储在另一个数据结构中(程序或函数取决于您的设计的程序或功能),则模拟对象不合适。所谓的“基于状态”的测试就是你想要的。您关心的结果是一个过程将正确的数据放入正确的变量中,并且它调用的内容只是一个实现细节。

如果您根据对象协作的消息传递通信协议对域进行建模,那么协议就是您关心的对象,以及对象存储哪些数据来协调它们在扮演角色的协议中的行为只是实现详情。在这种情况下,模拟对象是工作的正确工具,基于状态的测试将测试与不重要的实现细节紧密联系在一起。

在大多数面向对象的程序中,都有各种风格。一些代码将被编写为纯函数,转换不可变数据结构。其他代码将协调随时间改变其隐藏的内部状态的对象的行为。

至于高测试覆盖率,它实际上并没有告诉你那么多。低测试覆盖率会显示您测试不充分的地方,但高测试覆盖率并未向您显示代码已经过充分测试。例如,测试可以通过代码路径运行,因此可以增加覆盖率统计数据,但实际上不会对这些代码路径的作用做出任何断言。另外,真正重要的是程序的不同部分如何组合起来,哪个单元测试覆盖率不会告诉你。如果您想验证您的测试是否真的正在充分测试您的系统行为,您可以使用变异测试工具。这是一个缓慢的过程,所以这是你在每晚建立而不是每次办理登机手续时都会运行的。