容器内测试通常与使用模拟对象进行测试相反。然而,由于模拟对象只是模仿真实对象的行为,容器内测试不是在真实环境中真正测试系统的唯一方法吗?
作为容器内测试和模拟对象的部分替代,Spring提供了TestContext框架,它可以很好地初始化Spring,而不需要启动实际的应用程序容器(在我的例子中,是web应用程序服务器)。然而,这是一种有限的方法,因为它只初始化特定于Spring的特性,而不支持应用服务器-specific特性。所以你不能测试所有的东西。此外,由于它与实际web执行中使用的默认WebApplicationContext不是100%相同,这种方法不是有点老土吗?是不是很糟糕?
对于容器内测试,至少有Cactus (过时),Jeeunit (一个非常小的项目)和JBoss Arquillian (仍然是alpha,但看起来很有前途)。我没有看到这些项目被广泛使用,那么容器内测试有什么不好的地方吗?容器内测试经常被提及的主要缺点是执行速度慢。但是,当在持续集成环境和相对较小的项目中运行时,这应该不是问题。
总而言之:我们应该做容器内测试还是容器外测试?为什么?使用模拟对象或其他初始化机制(就像在Spring TestContext中一样)进行集成测试时,您会感到不舒服吗?
附注:我最近询问了categorization of integration test,这可能是相关的。
发布于 2010-07-14 21:00:05
然而,由于模拟对象只是模仿真实对象的行为,容器内测试不是在真实环境中真正测试系统的唯一方法吗?
我想简短的答案是肯定的,但是...我认为你的“集成测试的分类”问题非常相关。单元测试和集成测试都很重要,尽管它们的功能不同。
单元测试与代码密切相关,应该非常快速地启动和运行,应该经常由迭代代码的开发人员运行,并且通常在很高程度上使用模拟。这个想法是测试有问题的代码,而不是它的依赖项或集成点。将所有单元测试都放在容器中的问题是,它们运行的频率会降低,或者会浪费开发人员太多的时间。
我们已经将容器内/集成测试隔离在另一个依赖于代码项目的项目中。它们被设计成非常接近于生产配置--尽可能多。这些测试需要更长的时间来设置,运行的时间更长,并且使用像cruisecontrol这样的工具运行更有用。它们是手动运行的,特别是当我们接近发布版本或在开发稳定之后。我经常在去吃午饭或开会的时候启动集成测试。当集成测试发现一个bug时,我们会尝试编写一个单元测试,用mock来演示这个bug --这通常是困难的,也可能是不可能的。
我们通常有几个小的容器内测试,单元测试只是为了确保弹簧连接工作或测试一些基本功能,但其余的集成测试是在另一个项目中完成的。
尽管如此,两者之间并没有明显的区别。有时,我们将只处理大量数据的单元测试转移到集成测试,而有时集成测试运行得足够快,足够有价值,可以与代码一起包含。
发布于 2010-07-14 20:41:33
我会说我们应该同时做容器内和容器外的测试。我发现在容器内测试的主要问题是自动化所有东西的工作要多得多。你可以通过Spring的集成测试支持获得一些更便宜的胜利,但我们不应该欺骗自己,这涵盖了部署容器中测试的所有内容。
关于mock的话题,我发现它们可以在Spring的集成测试中发挥作用,但我更有可能使用带有封装结果的伪/存根服务来进行集成和容器内测试(我称之为系统测试)。
如果您不确定模拟和存根之间的区别,请查看此Martin Fowler article。
https://stackoverflow.com/questions/3245942
复制相似问题