【问题标题】:In-container testing vs. mock objects for integration testing用于集成测试的容器内测试与模拟对象
【发布时间】:2011-03-15 19:51:52
【问题描述】:

容器内测试通常与使用模拟对象进行测试相反。然而,由于模拟对象只是模仿真实对象的行为,容器内测试难道不是在其真实环境中真正测试系统的唯一方法吗?

作为容器内测试和模拟对象的部分替代方案,Spring 提供了TestContext 框架,它可以很好地初始化 Spring,而无需启动实际的应用程序容器(在我的例子中是 Web 应用程序服务器)。然而,这是一种有限的方法,因为它只初始化特定于 Spring 的特性,而不支持特定于应用程序服务器的特性。所以你不能测试一切。此外,由于它与实际 Web 执行中使用的默认 WebApplicationContext 不是 100% 相同,这种方法是不是有点 hackyish?不好吗?

对于容器内测试,至少有Cactus(过时)、Jeeunit(一个很小的项目)和JBoss Arquillian(仍然是 alpha,但看起来很有希望)。我没有看到这些项目中的任何一个被广泛使用,那么容器内测试有什么不好的地方吗?容器内测试经常提到的主要缺点是执行速度慢。但是,当在持续集成环境和相对较小的项目中运行时,这应该不是问题。

总结一下:我们应该进行容器内测试还是容器外测试,为什么?在集成测试中使用模拟对象或替代初始化机制(如在 Spring TestContext 中)会不会感觉不好?

附注:我最近询问了categorization of integration test,这可能是相关的。

【问题讨论】:

    标签: java testing mocking integration-testing application-server


    【解决方案1】:

    然而,作为模拟对象只是模仿真实对象的行为,不是容器内 测试在其真实环境中真正测试系统的唯一方法?

    我认为简短的回答是肯定的,但是...我认为您的“集成测试分类”问题非常相关。单元测试和集成测试很重要,尽管它们的功能不同。

    单元测试与代码密切相关,应该非常快速地启动和运行,应该经常由迭代代码的开发人员运行,并且通常高度使用模拟。这个想法是测试有问题的代码,而不是它的依赖关系或集成点。将单元测试全部放在容器中的问题是它们运行的​​频率会降低,或者会浪费太多的开发人员时间。

    我们已将我们的容器内/集成测试隔离在另一个项目的其他地方,并依赖于代码项目。它们旨在尽可能地模仿生产配置。这些测试需要更长的时间来设置、运行更长时间,并且对于通过类似cruisecontrol 的方式运行更有用。它们是手动运行的,尤其是在我们即将发布或开发稳定之后。我经常在去吃午饭或开会时启动集成测试。当集成测试发现错误时,我们会尝试编写一个单元测试,该测试还可以通过模拟演示该错误——这通常很难,而且可能是不可能的。

    我们通常在单元测试中进行一些小的容器内测试,以确保弹簧接线工作或测试一些基本功能,但其余的集成测试在另一个项目中完成。

    综上所述,两者之间并没有明确的区别。有时我们将只处理大量数据并花费很长时间的单元测试转移到集成测试中,有时集成测试运行得足够快,并且足够有价值,可以与代码一起包含。

    【讨论】:

    • 我在容器外运行单元测试非常好。实际上,我不明白您为什么要运行“几个小的容器内单元测试”来测试“弹簧接线”之类的东西?也许你在那里打错了,你的意思是“几个小的容器内集成测试”吗?另外,我是否理解正确:如果您的运行时配置发生更改,您必须将该设置复制到集成测试项目中吗?您如何实际运行/初始化容器内测试?也许有一些框架的帮助?
    • 我已编辑该部分。我的意思是我们在我们的单元测试集合中有几个集成测试,以确保所有的 Spring 连接工作。所有配置文件都包含在代码中——我们不会将任何配置复制到集成项目中。集成项目与生产代码共享相同的包路径,因此可以加载所有相同的 src/main/resource(我们使用 mvn)配置。
    【解决方案2】:

    我想说我们应该同时进行容器内和容器外测试。我在容器内测试中发现的主要问题是自动化所有内容需要更多的工作。借助 Spring 的集成测试支持之类的东西,您可以获得一些更便宜的胜利,但我们不应该自欺欺人地认为这涵盖了在部署容器中进行测试的所有内容。

    关于 mocks,我发现它们可以在 Spring 的集成测试中发挥作用,但我更有可能使用带有罐装结果的假/存根服务来进行集成和容器内测试(我会调用系统测试)。

    如果您不确定模拟和存根之间的区别,请查看此Martin Fowler article

    【讨论】:

    • 您使用什么库进行容器内测试?让我着迷的是,每个容器内测试框架(Cactus、jeeunit、Arquillian)似乎都实现了对不同技术的特定支持,例如 CDI、EJB、Servlet 等。难怪支持所有这些都需要一些额外的配置: / 感谢文章的指点,我不得不承认我在这种情况下经验很少。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    • 2022-07-12
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    • 2011-06-13
    • 2014-07-22
    相关资源
    最近更新 更多