如何修复在本地通过但在 CI 服务器中失败的 AssertJ Swing 测试?

Joh*_*Doe 5 java continuous-integration swing gui-testing assertj

我使用 Assertj Swing(版本 3.17.0)进行的 GUI 单元测试都在本地通过,但有时在 CI 服务器中失败。如果我重试足够长的时间,最终测试套件会变成绿色。我很难弄清楚如何修复这些测试。

我使用 Java 8 和 Github Actions 作为 CI。正如类似问题中所建议的,我使用 VNC 在 CI 上无头运行这些测试,命令如下:

./execute-on-vnc.sh mvn -B -f pom.xml clean verify
Run Code Online (Sandbox Code Playgroud)

这是失败的测试示例(我正在模拟控制器,只是验证单击按钮实际上会使用正确的参数调用控制器方法):

@Mock private ItemController controller;

@Test @GUITest
public void testAddItemButtonShouldDelegateToControllerAddItem() {
    window.textBox("itemIdTextField").enterText("1");
    window.textBox("itemNameTextField").enterText("Some Item");
    window.button(JButtonMatcher.withName("addItemButton")).click();
    verify(controller).addItem(new Item("1", "Some Item"));
}
Run Code Online (Sandbox Code Playgroud)

下面是处理 JButton 上的点击的非常直接的代码:

addItemButton.addActionListener(e ->
    controller.addItem(new Item(itemIdTextField.getText(), itemNameTextField.getText()))
);
Run Code Online (Sandbox Code Playgroud)

测试每次都在本地通过,没有任何问题,但在 CI 上经常失败,并出现以下错误:

testAddItemButtonShouldDelegateToControllerAddItem(com.example.view.swing.ItemSwingViewTest)
Time elapsed: 0.985 sec  <<< FAILURE!
Wanted but not invoked:

controller.addItem(
  Item{id='1', name='Some Item'}
);

Actually, there were zero interactions with this mock.
Run Code Online (Sandbox Code Playgroud)

我一直无法找出这些不稳定测试的原因。

我尝试过的事情:

  • 为 verify() 方法添加了 5 秒超时
  • 无效的 CI maven 缓存并重新运行测试
  • 使用其他 Java 版本(9、11 和 13)在 CI 上进行了测试

一切都没有运气。难道我做错了什么?