【问题标题】:Integration tests randomly fail or throw error when run by maven由 maven 运行时,集成测试随机失败或抛出错误
【发布时间】:2014-09-29 13:31:12
【问题描述】:

我正在使用 maven 运行一套集成测试,大约 10% 的测试会失败或抛出错误。但是,当我启动服务器并从我的 IDE(intellij 想法)手动运行单个失败的测试时,它们都没有问题地通过。这个问题的原因可能是什么?

【问题讨论】:

  • 错误是什么?也许您没有在每次测试之间正确清理资源。这可以解释为什么它们在单独运行时通过但在完全运行时失败。
  • 我一直使用 mvn clean install 运行,所以我认为资源是干净的,或者您是指清理整个 .m2 存储库并再次运行测试?
  • 失败和错误真的是随机的。当我正在测试一个数据库时,它会抛出诸如“表不存在”或“SQL 语法错误”之类的错误。
  • 嗯,不,我指的是您的代码使用的资源,例如数据库。 clean maven 命令只清理生成的文件,但我认为这对你的情况没有帮助(因为一切都编译得很好)。也不要清理你的整个 .m2 存储库,我想不出这会有所帮助的情况。在任何情况下,依赖管理操作都应该通过 maven 命令和/或 pom 配置来完成。尝试隔离错误(例如“表不存在”错误),然后尝试找出表不存在的原因(可能是因为它是在其他地方创建的)。
  • 每次运行测试套件之前,我都会清理整个数据库。这真的很奇怪,因为表的创建和删除都是由集成测试完成的,当由 maven 运行时它们会失败。谢谢您的帮助!我会尝试更深入地研究它。

标签: java maven intellij-idea integration-testing maven-plugin


【解决方案1】:

这几乎总是由以不一致的顺序运行的单元测试或通过分叉测试并行运行的两个测试之间的竞争条件引起的。如果测试 #1 先完成,则通过。但是,如果 Test #2 先完成,它将使测试资源(例如测试数据库)处于备用状态,从而导致 Test #1 失败。这在数据库测试中很常见,尤其是当一个或多个更改数据库时。即使在 IDEA 中,您可能会发现 com.example.FooTest 类中的所有测试在您运行该类时总是通过。但是,如果您运行 com.example 包中的所有测试或项目中的所有测试,有时(甚至总是)FooTest 中的测试会失败。

解决方法是确保您的测试在运行时始终保持一致的状态。 (这是良好单元测试的指导原则。)您需要注意通过 @Before@BeforeClass@After@AfterClass 注释(或 TestNG 等价物)进行测试设置和拆卸。我推荐谷歌搜索database unit testing best practices。对于数据库测试,在事务中运行测试可以防止这些类型的问题。这样,无论测试通过还是失败,数据库都会回滚到其起始状态。 Spring 对 JDBC 数据库测试有一些很好的支持。 (即使您的项目不是 Spring 项目,这些类也非常有用。)阅读11.2.2 Unit Testing support Classes 部分并查看AbstractTransactionalJUnit4SpringContextTests / AbstractTransactionalTestNGSpringContextTests 类和@TransactionConfiguration 注释(后一个来自运行 Spring 上下文)。还有其他数据库测试工具,例如DbUnit

【讨论】:

  • 有什么方法可以强制测试始终以相同的顺序运行?
  • IDEA 没有遵循最佳实践的理念,不允许“不理想的实践”。理想情况下,单元测试应该彼此独立。更好的解决方案是使用 @BeforeTest/setup() 和/或 @AfterTest/teardown() 方法使测试环境进入已知的基线状态。如果 IDEA 允许以特定顺序运行测试,不同的 IDE 或构建系统仍然会出现问题。也就是说,JUnit 4.11 添加了对通过@FixMethodOrder 运行的顺序测试进行一些控制的能力。请参阅stackoverflow.com/q/3693626的答案#2
  • 是的,我同意你的看法。只是我有一系列测试失败。我正在寻找修复它的想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-27
  • 1970-01-01
  • 1970-01-01
  • 2015-09-19
  • 1970-01-01
相关资源
最近更新 更多