4

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

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

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

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

一个小注:我最近询问了集成测试的分类,这可能是相关的。

4

2 回答 2

3

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

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

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

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

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

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

于 2010-07-14T13:00:04.990 回答
2

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

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

如果您不确定 mocking 和 stubbing 之间的区别,请查看这篇Martin Fowler 文章

于 2010-07-14T12:41:33.343 回答