The cardinal rule of Swing threading states that all access to all Swing components should be done in the event dispatch thread (EDT). To avoid unexpected behavior in your GUI tests (e.g. random test failures), this rule also applies to test code.
If you follow these tips you ensure that your GUI tests respect Swing's threading rules:
GuiActionRunner
using a GuiQuery
or GuiTask
, because JUnit and TestNG tests do not run on
the EDT. More details below on this page.FailOnThreadViolationRepaintManager
to catch EDT-access
violations. More details below on this page.Alex Ruiz wrote an entry on his blog about how to write EDT-safe GUI tests.
AssertJ Swing performs all access to Swing components in the EDT. AssertJ Swing also exposes a convenient mechanism to access Swing components in the EDT from your test code. This mechanism involves one (with lambda expressions) to three (traditional way) classes:
GuiQuery
or GuiTask
(or Callable/Runnable via lambda expressions) in the EDT, rethrowing any exceptions thrown when executing any GUI
action in the EDT.* If you use lambda expressions you don't need to use this class directly.
When you would like to read the text of a label, execute the following code:
final JLabel nameLabel = ... // get a reference to a JLabel
String text = GuiActionRunner.execute(() -> nameLabel.getText());
When you would like to set the text of a label, execute:
final JLabel nameLabel = ... // get a reference to a JLabel
GuiActionRunner.execute(() -> nameLabel.setText("Name:"));
AssertJ Swing provides the class
FailOnThreadViolationRepaintManager
that forces a test failure if access to Swing components is not performed on the EDT. This repaint manager
is based on ThreadCheckingRepaintManager
by Scott Delap and Alex Potochkin. For more details
about how to check if GUI component is done outside the EDT, please check Alex Potochkin's article
Debugging Swing, the final summary.
Installing FailOnThreadViolationRepaintManager
is pretty simple. The following example shows
how to install it in the class-level setup method of a JUnit test:
@BeforeClass
public static void setUpOnce() {
FailOnThreadViolationRepaintManager.install();
}
When using Sun's JVM, a new instance of FailOnThreadViolationRepaintManager
will be set as the
default repaint manager in Swing once and only once, regardless of the number of times install()
is called. On other JVMs this optimization is not guaranteed.
Once a FailOnThreadViolationRepaintManager
is installed, it will throw an
EdtViolationException
if a GUI test is not accessing Swing components in the EDT.