JavaFX 应用程序线程在 JUnit 测试期间退出
JavaFX application thread exits during JUnit test
我正在使用 JUnit 测试 JavaFX 应用程序,在大多数情况下,我使用 Basic JUnit test for JavaFX 8 中的 @Rule 方法。然而,在某些情况下这种方法不起作用,所以我手动设置 JavaFX 平台,并在必要时调用 Platform.runLater()。
似乎正在发生的事情是,在某些时候 JavaFX 应用程序线程正在消失,这意味着后续测试锁定,因为 Platform.runLater() 调用永远不会 return - 这就是我添加的原因例如超时。我已经通过调用 Thread.getAllStackTraces()
证明了这一点
- 是的,我知道 JemmyFX,我可能很快就会转向它,但我仍然想了解这里发生了什么...
代码
public class JavaFxThreadJUnit {
private static boolean setup;
private Stage stage;
@Before
public void before() throws Exception {
setupJavaFX();
Platform.setImplicitExit(true);
CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(() -> {
stage = new Stage();
stage.show();
latch.countDown();
});
latch.await(5, TimeUnit.SECONDS);
}
@After
public void after() throws Exception {
CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(() -> {
stage.hide();
latch.countDown();
});
latch.await(5, TimeUnit.SECONDS);
}
@Test
public void foo() throws Exception {
// test stuff...
System.out.println("foo test: "
+ Thread.getAllStackTraces().keySet().stream().map(Thread::getName).collect(Collectors.toList()));
}
@Test
public void bar() throws Exception {
// test stuff...
System.out.println("bar test: "
+ Thread.getAllStackTraces().keySet().stream().map(Thread::getName).collect(Collectors.toList()));
}
// https://gist.github.com/andytill/3835914
public static void setupJavaFX() throws InterruptedException {
if (setup) {
return;
}
long timeMillis = System.currentTimeMillis();
final CountDownLatch latch = new CountDownLatch(1);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// initializes JavaFX environment
new JFXPanel();
latch.countDown();
}
});
System.out.println("javafx initialising...");
latch.await();
System.out.println("javafx is initialised in " + (System.currentTimeMillis() - timeMillis) + "ms");
setup = true;
}
}
输出...JavaFX 应用程序线程在那里,然后就消失了...
javafx initialising...
javafx is initialised in 327ms
bar test: [Thread-3, ReaderThread, AWT-Shutdown, AWT-Windows, Thread-2, Finalizer, JavaFX Application Thread, Signal Dispatcher, Java2D Disposer, AWT-EventQueue-0, main, Attach Listener, Reference Handler, QuantumRenderer-0]
foo test: [Thread-3, ReaderThread, Java2D Disposer, AWT-Windows, Thread-2, main, Finalizer, Attach Listener, Reference Handler, Signal Dispatcher]
关卡关闭似乎触发了 "implicit exit"。我仍然有兴趣知道为什么这不会影响使用 @Rule 方法的测试...
解决方法:
Platform.setImplicitExit(false)
我正在使用 JUnit 测试 JavaFX 应用程序,在大多数情况下,我使用 Basic JUnit test for JavaFX 8 中的 @Rule 方法。然而,在某些情况下这种方法不起作用,所以我手动设置 JavaFX 平台,并在必要时调用 Platform.runLater()。
似乎正在发生的事情是,在某些时候 JavaFX 应用程序线程正在消失,这意味着后续测试锁定,因为 Platform.runLater() 调用永远不会 return - 这就是我添加的原因例如超时。我已经通过调用 Thread.getAllStackTraces()
证明了这一点- 是的,我知道 JemmyFX,我可能很快就会转向它,但我仍然想了解这里发生了什么...
代码
public class JavaFxThreadJUnit {
private static boolean setup;
private Stage stage;
@Before
public void before() throws Exception {
setupJavaFX();
Platform.setImplicitExit(true);
CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(() -> {
stage = new Stage();
stage.show();
latch.countDown();
});
latch.await(5, TimeUnit.SECONDS);
}
@After
public void after() throws Exception {
CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(() -> {
stage.hide();
latch.countDown();
});
latch.await(5, TimeUnit.SECONDS);
}
@Test
public void foo() throws Exception {
// test stuff...
System.out.println("foo test: "
+ Thread.getAllStackTraces().keySet().stream().map(Thread::getName).collect(Collectors.toList()));
}
@Test
public void bar() throws Exception {
// test stuff...
System.out.println("bar test: "
+ Thread.getAllStackTraces().keySet().stream().map(Thread::getName).collect(Collectors.toList()));
}
// https://gist.github.com/andytill/3835914
public static void setupJavaFX() throws InterruptedException {
if (setup) {
return;
}
long timeMillis = System.currentTimeMillis();
final CountDownLatch latch = new CountDownLatch(1);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// initializes JavaFX environment
new JFXPanel();
latch.countDown();
}
});
System.out.println("javafx initialising...");
latch.await();
System.out.println("javafx is initialised in " + (System.currentTimeMillis() - timeMillis) + "ms");
setup = true;
}
}
输出...JavaFX 应用程序线程在那里,然后就消失了...
javafx initialising...
javafx is initialised in 327ms
bar test: [Thread-3, ReaderThread, AWT-Shutdown, AWT-Windows, Thread-2, Finalizer, JavaFX Application Thread, Signal Dispatcher, Java2D Disposer, AWT-EventQueue-0, main, Attach Listener, Reference Handler, QuantumRenderer-0]
foo test: [Thread-3, ReaderThread, Java2D Disposer, AWT-Windows, Thread-2, main, Finalizer, Attach Listener, Reference Handler, Signal Dispatcher]
关卡关闭似乎触发了 "implicit exit"。我仍然有兴趣知道为什么这不会影响使用 @Rule 方法的测试...
解决方法:
Platform.setImplicitExit(false)