Maven-surefire-plugin测试在Jenkins构建中失败但在本地成功运行?

时间:2016-03-17 23:43:07

标签: java maven unit-testing jenkins maven-surefire-plugin

我有一个maven项目,由maven-surefire-plugin执行测试。我观察到和处理的奇怪现象是在本地运行

mvn clean install

执行我的测试,导致成功构建0失败和0错误。

现在,当我将此应用程序部署到Jenkins尝试构建的远程仓库时,我会收到各种随机的EasyMock错误,通常是这种错误:

java.lang.IllegalStateException: 3 matchers expected, 4 recorded. at org.easymock.internal.ExpectedInvocation.createMissingMatchers

这是遗留的遗留应用程序,我们知道很多这些测试都有缺陷,如果不能正确使用EasyMock,但是我处于测试执行的状态,我在本地成功构建但不在Jenkins中

我知道这些测试的执行顺序并不能保证,但我想知道我如何能够反省Jenkins构建管道与本地的不同之处以帮助识别问题?

我有什么办法可以按照他们在本地完成的方式强制执行测试吗?在这一点上,我简单地排除了许多麻烦的测试类,但似乎无论我看到Jenkins多少次失败,我要么修复问题要么排除测试类,我只是发现它抱怨其他一些测试以前没有提过的课程。

任何想法如何处理这样的情况?

2 个答案:

答案 0 :(得分:2)

我已经尝试了相似的情况,并且我的原因显然是测试实现的一些并发问题

并且,在阅读你的评论之后:

  

我实际做了什么修复它(就像魔法我是对的?)是maven-surefire插件,我设置属性reuseForks = false,forkCount = 1C,这只是1 *(机器的CPU数量) )。

...我更确信您的测试存在并发问题。并发性并不容易诊断,特别是当您的实验在一个CPU上运行正常时。但是当你在另一个系统(通常更快或更慢)上运行时,可能会出现竞争条件。

我强烈建议您逐一审核您的测试并确保每个测试逻辑上隔离

  • 他们不应该依赖于预期的先前状态(文件,数据库等)。相反,他们应该在每次执行之前准备好正确的设置
  • 如果他们同时修改可能干扰其他测试执行的公共资源(文件,数据库,单例等),则每个断言必须根据需要进行同步,并考虑到其初始状态未知:

错误的测试:

MySingleton.getInstance().put(myObject);
assertEquals(1, MySingleton.getInstance().size());

正确的测试:

synchronized(MySingleton.getInstance())
{
    MySingleton.getInstance().put(myObject);
    assertTrue(MySingleton.getInstance().contains(myObject));
}

审核的一个良好起点是检查其中一个失败的测试并向后跟踪执行以找出失败的根本原因。

明确设置测试的顺序不是一个好习惯,即使我知道它是可能的,我也不会向你推荐它,因为它只会隐藏问题的实际原因。可以认为,在真实的生产环境中,通常不会保证执行的命令。

答案 1 :(得分:1)

JUnit测试运行顺序是非确定性的。

两台机器上的Java和Maven版本是否相同?如果是,请确保您使用的是最新的maven-surefire-plugin版本。此外,请确保使用带有Maven构建步骤的Freestyle Jenkins作业而不是Maven项目类型。使用正确的Jenkins构建类型可以直接修复构建问题或者为您提供更好的错误,以便您可以诊断实际问题。

您可以打开Maven调试日志以查看正在运行的订单测试。每个测试都应设置(并且可能拆除)自己的测试数据,以确保测试可以独立运行。也许看到测试顺序会给你一些关于哪些类不恰当地依赖于其他类的线索。并且 - 如果应用程序使用缓存,请确保在测试之间清除缓存(或根据测试需要执行的操作显式填充)。还要考虑一次运行测试一个包来隔离罪犯 - 多个surefile插件执行可能会有用。

同时检查应用程序是否存在类路径问题。 This answer有一些清理类路径的建议。

另一种可能性:切换到更高版本的JUnit可能会有所帮助 - 除非该应用程序使用的是Spring 2.5.6.x.如果应用程序使用的是Spring 2.5.6.x且无法升级,则可能使用的最高版本的JUnit 4.x为4.4。更高版本的JUnit是not compatible with Spring Test 2.5.6,可能会导致难以诊断的测试错误。