I am working on a fairly large project which includes a set of custom JavaFX components. For each custom component which is meant to be reused, I have started to write a set of automated tests using JemmyFX and JUnit. During development, I run these from inside Eclipse Juno.
Running the entire suite of tests at once has proven difficult. The problem seems to stem from the fact since I want to test multiple components, I would ideally run a different application for each (so that tests performed on one component do not affect other tests).
I created a base class which does the following:
@BeforeClass public static void beforeClass() { Thread t = new Thread("JavaFX Init Thread") { @Override public void run() { Application.launch(UITester.class, new String[0]); } }; t.setDaemon(true); t.start(); }
Using this base class, I created a separate class with @Test
tests for each custom control. When I run this test suite, the first test case runs fine, but the rest fail:
Exception in thread "JavaFX Init Thread" java.lang.IllegalStateException: Application launch must not be called more than once
I have tried the following ways to address this problem:
Shut down the application
I added the following to the base class:
@AfterClass public static void afterClass() { Platform.exit(); }
Same problem persists. Perhaps because the VM is not restarted between tests?
Put in a guard against restarting the application
I put in a static variable to check and see if perhaps the application is already running. This makes the problem go away when I run the tests from Eclipse. When I run them from the command line, the problem is still there. Not good for when we try to run these tests on the integration server.
Catch the IllegalStateException
This is an odd one. I can catch the exception, and most of my problems go away, except for the fact that every 4 or 5 runs of the entire test suite Ubuntu crashes to the shell and I have to log back in.
So, how do I best write tests for a large suite of custom controls? Is my approach incorrect?
AppExecutor.executeNoBlock(UITester.class);
As far as I understand it, it does the same thing as my original sample (and was the call I originally made to start the tests, with the same effect). – Heterodyne