我有一个 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 中失败.
我知道这些测试的执行顺序无法保证,但我想知道如何反射(reflection) Jenkins 构建管道与本地构建管道中的不同之处以帮助识别问题?
我可以做些什么来强制以本地完成的方式执行测试吗?此时,我只是排除了许多麻烦的测试类,但似乎无论我多少次看到 Jenkins 失败,我要么解决问题,要么排除测试类,我只是发现它提示其他一些测试之前没有提到的类。
有什么想法可以处理这样的情况吗?
最佳答案
我已经尝试过类似的情况,而我的原因显然是测试实现中的一些并发问题。
并且,在阅读您的评论后:
What I actually did that fixed it (like magic am I right?) is for the maven-surefire plugin, I set the property reuseForks=false, and forkCount=1C, which is just 1*(number of CPU's of machine).
...我更加确信您的测试存在并发问题。诊断并发并不容易,特别是当您的实验在一个 CPU 上运行正常时。但是,当您在另一个系统(通常更快或更慢)上运行它时,可能会出现竞争条件。
我强烈建议您逐一检查您的测试,并确保每一项在逻辑上是独立的:
- 它们不应依赖于预期的先前状态(文件、数据库等)。相反,他们应该在每次执行之前准备适当的设置。
- 如果他们同时修改可能干扰其他测试执行(文件、数据库、单例等)的公共(public)资源,则每个断言都必须根据需要进行同步,并考虑到其初始状态未知:<
错误的测试:
MySingleton.getInstance().put(myObject);
assertEquals(1, MySingleton.getInstance().size());
正确的测试:
synchronized(MySingleton.getInstance())
{
MySingleton.getInstance().put(myObject);
assertTrue(MySingleton.getInstance().contains(myObject));
}
审查的一个良好起点是检查失败的测试之一并向后跟踪执行情况以找到失败的根本原因。
明确设置测试顺序并不是一个好的做法,即使我知道这是可能的,我也不会推荐给您,因为它只会隐藏问题的实际原因。认为,在实际的生产环境中,执行的顺序通常是无法保证的。
关于java - Maven-surefire-plugin 测试在 Jenkins 构建中失败但在本地运行成功?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36073648/