对于集成测试应该嘲笑什么?

时间:2013-07-26 10:57:39

标签: unit-testing mocking integration-testing

在阅读以测试为导向的面向对象的成长软件时,我了解了测试隔离和测试脆弱性。我们认为每个测试都应该对一段代码或功能非常具体,并且应该将测试代码覆盖的重叠保持在最低限度。 隐含的理想是代码中的每个更改都应该导致只打破一个测试。 避免花费时间经历多次破坏测试,以确认一个变化是原因,以及是否通过测试修改来修复。

现在这对于单元测试来说似乎很容易,它们本质上是非常孤立的。 但是,当通过集成测试呈现时,似乎很难避免多个测试执行相同的代码路径,特别是在单元测试之外运行时。

所以我的问题是,在进行集成测试时应该嘲笑哪些依赖项?有什么可以嘲笑的吗?是否应该测试单个执行路径,并且模拟与此代码路径不直接相关的所有副作用?

我正在尝试进行成对集成测试。测试两个对象之间的一个关系,并模拟其他一切。然后,除了通过成对形成完整的端到端测试链之外,其中任何一个对象的更改对其他集成测试的影响应该最小。

感谢您提供任何信息..

编辑:为了澄清,我基本上问“如何在正常的开发过程中避免大量失败的集成测试?”。我假设是通过使用模拟来实现的,为什么我要问模拟什么。

更新:我发现了一个非常有趣的关于J.B.Rainsberger的集成测试的讨论,我认为这个答案相当好,如果可能有点争议的话。标题是“集成测试是一个骗局”,所以你可以猜测,他根本不提倡集成测试(端到端类型测试)。认为积分测试总是远远低于彻底测试可能的相互作用所需的量(由于组合爆炸),并且可能给出错误的信心。 相反,他建议他称之为协作测试和合同测试。这是一个90分钟的谈话,不幸的是白板不是很清楚,没有代码示例,所以我仍然围绕它。当我有清楚的解释时,我会在这里写出来!除非别人打败我...

以下是合同测试的简要概述。听起来像契约类型断言,我相信可以/将在C ++中以非虚拟接口模式实现。

http://thecodewhisperer.tumblr.com/post/1325859246/in-brief-contract-tests

集成测试是一个骗局视频讲话: http://www.infoq.com/presentations/integration-tests-scam

  

要点:

     

集成测试是一个骗局。你可能写的是2-5%   您需要进行彻底测试的集成测试。你很可能   在整个地方重复单元测试。您的集成测试   可能在整个地方互相复制。什么时候整合   测试失败,谁知道什么坏了?学习双管齐下的攻击   解决了这个问题:协作测试和合同测试。

4 个答案:

答案 0 :(得分:1)

对于集成测试,您应该模拟最小数量的依赖项以使测试正常工作,但不能少于: - )

由于系统中组件的集成显然是您希望在集成测试期间进行测试的,因此您应尽可能使用实际实现。但是,有一些组件你显然想要模拟,因为你不希望你的集成测试开始邮寄你的用户。当你不模仿这些依赖关系时,你显然很嘲笑。

这并不意味着您不应该允许集成测试发送邮件,但至少您要将邮件组件替换为仅将邮件发送到某个内部测试邮箱的邮件组件。

答案 1 :(得分:1)

单元测试应该有模拟对象,但是集成测试应该有很少的模拟(否则什么是集成?)我认为做成对模拟是不合适的;它会导致大量测试的爆炸,这些测试可能需要很长时间以及大量的复制和粘贴代码,如果需求发生变化或以后添加新功能,这将很难改变。

我认为在集成测试中没有任何模拟是没关系的。您应该在单元测试中模拟所有内容,以便知道每个单元单独按预期工作。集成测试测试所有内容都连接在一起。

答案 2 :(得分:1)

对于集成测试,我倾向于模拟服务而不是表示,例如使用mirage而不是第三方REST API和Dumpster而不是真正的SMTP服务器。

这意味着您的代码的所有层都经过测试,但没有第三方进行测试,因此您可以自由地重构而不必担心测试会失败。

答案 3 :(得分:0)

合同/协作者测试模式的讨论(由JB Rainsberger在&#34中描述;集成测试是一个骗局"在上面的问题中提到)。关于这里的问题 - 我将他的演讲解释为当你拥有服务端和客户端的代码时,你根本就不需要任何集成测试。相反,你应该能够依靠实施合同的模拟。

该演讲对于模式的高级描述是一个很好的参考,但并没有详细说明(至少对我来说)如何定义或引用协作者的合同。

需要合同/协作者模式的一个常见示例是在API的服务器/客户端(您拥有两者的代码)之间。以下是我实施它的方法:

定义合同:

首先定义API架构,如果您的API使用JSON,您可能会考虑JSONSchema。架构定义可以被视为"合同"的API。 (作为旁注,如果您要这样做,请确保您了解RAML或Swagger,因为它们本质上使编写JSONSchema API变得更加容易)

创建实施合同的灯具:

  • 在服务器端,模拟客户端请求以允许对请求/响应进行单元测试。为此,您将创建客户端请求夹具(也称为模拟)。定义API后,根据JSONSchema验证灯具以确保它们符合要求。有许多模式验证器 - 我目前使用AJV(Javascript)和jsonschema(Python),但大多数语言应该有一个实现。

  • 在客户端,您可能会模拟服务器响应以允许对请求进行单元测试。遵循与服务器相同的模式,通过JSONSchema验证请求和响应夹具。

如果客户端和服务器都在根据合同验证其设备,那么每当API合同发生变化时,双方的过时实施都将无法通过JSONSchema验证,并且您将知道它的时间更新您的灯具以及可能依赖这些灯具的代码。

相关问题