Lately, I noticed that one of the main topics in the FEST mailing list is violation of Swing’s threading policy in UI tests. Surprisingly, this subject is not really referenced directly. Most of the time, it appears in the form of questions, code snippets or test cases not related to Swing threading at all. It seems like we are still not fully aware of the event dispatch thread (EDT,) even though it has been around for many years (10+ maybe?)
In this blog entry, I’ll try my best to explain how to write EDT-safe UI tests. Some of the ideas are pretty general, and can be practiced even when not using FEST.
Brief explanation of Swing’s threading policy
Swing is a single threaded UI toolkit. Since it is not thread-safe, all Swing code must be executed in the EDT. As the official documentation states, invoking Swing code from multiple threads risks thread interference or memory consistency errors.
Swing’s threading policy basically states the following:
- Swing components must be created in the EDT
- Swing components must be accessed in the EDT, unless calling methods documented as “thread safe”
Pretty simple, eh? Unfortunately, it is too easy to break these rules. Swing does not provide any run-time checks for correct EDT usage and, most of the time, we can get away with an apparently “well behaved” Swing UI that breaks these rules.
As a side note, the 3rd-party Swing L&F, Substance, checks for violations of Swing threading rules at run-time, and it’s tastefully beautiful.
UI tests and the EDT
Writing EDT-safe UI tests is a little different than writing UI production code. The main difference is that calls in the EDT must always be synchronous. The thread running the test (either a TestNG or JUnit one) must wait for the code executed in the EDT to finish in order to continue its execution, to prevent unexpected results.
The following image illustrates how a test that involves verifying that the text of some JLabel changes when selecting a JCheckBox needs to be executed.

Tips for writing EDT-safe UI Tests with FEST
-
Use FEST’s
FailOnThreadViolationRepaintManagerto detect EDT-access violations
FailOnThreadViolationRepaintManager, based on the work of Scott Delap and Alexander Potochkin, will make UI tests fail if there is any EDT-access violation in both UI tests and production code. The best place to use it is the “set up” method marked with the annotation@BeforeClass:@BeforeClass public void setUpOnce() { FailOnThreadViolationRepaintManager.install(); }
Alternatively, UI tests can subclass FEST’s
FestSwingTestngTestCaseorFestSwingJunitTestCase, which already installFailOnThreadViolationRepaintManager. -
Use FEST’s
GuiActionRunnerto execute code in the EDT synchronously
When writing FEST, we originally tried to useSwingUtilities‘invokeAndWaitto make calls in the EDT synchronously. Unfortunately, we ended up with too manyOutOfMemoryErrors when running our UI tests. Instead we wrote our ownGuiQueryandGuiTask.GuiQueryis useful when creating Swing components or reading properties from a Swing component.GuiTaskis similar toGuiQuery, but its purpose is to perform some action (or task) in the EDT without returning any value.The following example shows how to use a
GuiQueryto create aJLabel:JLabel myLabel = GuiActionRunner.execute(new GuiQuery<JLabel>() { public JLabel executeInEDT() { return new JLabel("A Test"); } });
The following example shows how to use a
GuiTaskto select aJCheckBox:// static import of GuiActionRunner.execute execute(new GuiTask() { public void executeInEDT() { myCheckBox.setSelected(true); } });
The following example shows how to use a
GuiQueryto read the text of aJLabel:String text = execute(new GuiQuery<String>() { public String executeInEDT() { return myLabel.getText(); } });
Both
GuiTaskandGuiQueryshould be used when accessing Swing components directly from our tests. -
Always call
waitForIdlein FEST’sRobotafter usingGuiActionRunnerThe method
waitForIdlewill pause the test until all events have been processed in the EDT (step #3 in the figure above.) -
To improve performance, consolidate as many method calls in
GuiActionRunneras possible
We have found that we can greatly improve performance in our UI tests by consolidating as many calls in the EDT as possible. For example, instead ofString text = execute(new GuiQuery<String>() { public String executeInEDT() { return myLabel.getText(); } }); Dimension size = execute(new GuiQuery<Dimension>() { public Dimension executeInEDT() { return myLabel.getSize(); } });
we can consolidate both calls into a single trip to the EDT
Pair<String, Dimension> textAndSize = execute(new GuiQuery<Pair<String, Dimension>>() { public Pair<String, Dimension> executeInEDT() { return new Pair<String, Dimension>(myLabel.getText(), myLabel.getSize()); } });
where
Pairis a class in the packageorg.fest.swing.util. -
Do not use FEST’s
GuiActionRunnerto call “thread safe” Swing methodsFor example, all the methods that add event listeners to Swing components are synchronized. There is not need to take care of threading in this case.
-
Do not use FEST’s
GuiActionRunnerto call FEST’s API
All methods in FEST are already EDT-safe.
Comments/suggestions are always welcome :)
Enjoy!
My name is Alex Ruiz. I'm a programmer with special interest in Java, API design, testing and OOP. I'm the creator of 


#1 by Per Rovegård on November 18, 2009 - 7:57 am
Thanks for the great tips! Question about #3 though. I notice that this does not seem to be enforced in FEST itself.
For example, if I inspect calls to the ComponentShowingQuery.isShowing method, which uses GuiActionRunner.execute, none of the call sites call waitForIdle after calling isShowing.
So, I wonder if this is a valid recommendation in general or if the recommendation rather applies in specific cases?
Thanks.
#2 by Alex Ruiz on November 18, 2009 - 8:14 am
Good catch!
I’d say calling ‘waitForIdle’ is not necessary when performing a GuiQuery that only *reads* property values, without changing the state of the UI.
I’d prefer to say “always call ‘waitForIdle’” even if no modifications are made, to simplify things and avoid confusion. The “worst case” scenario is that there are no changes in the UI, and EDT has no actions queued, and ‘waitForIdle’ returns immediately.
FEST itself does not enforce because GuiActionRunner and Robot don’t know about each other: you could use GuiActionRunner without a Robot in your tests.
I hope I answered your question :)
Cheers!
#3 by Per Rovegård on November 19, 2009 - 1:10 am
Thanks, that’s what I suspected. Modifying components might generate events that you need to let happen before continuing, whereas reading something should be safe.
I realize that GuiActionRunner itself cannot enforce the idle wait. I was more wondering about methods such as BasicRobot.focus(Component, boolean), for example, which calls ComponentRequestFocusTask.giveFocusTo, but then does not wait for an idle event queue. It seems to me that this is a situation where the robot ought to call waitForIdle afterwards, right?
#4 by Alex Ruiz on November 19, 2009 - 6:04 am
Another good catch! :)
In the case of ‘focus’, that code was written before GuiActionRunner was introduced to FEST. Currently it waits till the component has focus, and fails if the component didn’t get it.
You are right, it should call ‘waitForIdle’ :)
Now that I revisit this method, I’m not sure ‘waitForIdle’ is good enough, since requesting focus is not a guaranteed action (per Swing Javadocs.) ‘waitForIdle’ will wait till the EDT has no actions to process, but the component might never get the focus. In the case of testing, this is a big issue, since tests would expect a component to have focus.
In short, I need to call ‘waitForIdle’ *and* check if the component has focus :)
(Can you please file a ticket?)
Thanks Per!
#5 by a on December 3, 2009 - 5:30 am
nice post but
execute(new GuiTask() {
public JLabel executeInEDT() {
myCheckBox.setSelected(true);
}
});
should be
final myCheckBox = ….;
execute(new GuiTask() {
public voidexecuteInEDT() {
myCheckBox.setSelected(true);
}
});
#6 by Bruce Alspaugh on January 15, 2010 - 11:28 am
Is it possible to somehow tell the test runner (either JUnit or TestNG) that you would like to run a particular test method on the EDT? Maybe specify in the annotation that the test is supposed to be submitted to a java.util.concurrent.Executor that executes its tasks on the EDT. In other words say something similar to:
@Test(executor=SwingExecutor.class)
public void testMySwingComponentOnEDT() throws Exception {
// all this test code gets run on the Swing EDT
}
The test runner will wait for the test method to finish to see if it throws an exception. If the test method throws an exception, it will be re-thrown back onto the original test runner thread. I think it would make the test code cleaner if we could avoid all the nested inner classes.
#7 by Alex Ruiz on January 15, 2010 - 11:37 am
Hi Bruce,
We currently don’t support such feature, mainly because there haven’t been any requests for it.
I can see this feature is useful, as long as you don’t use the AWT Robot (or FEST’s Robot,) because they cannot run in the EDT.
Can you please file a ticket at http://jira.codehaus.org/browse/FEST ? I’d like to keep this conversation there :)
Thanks!
#8 by Luke Nezda on February 4, 2010 - 8:02 pm
Does combo of JUnit 4 @Test and @RunsInEDT do this?
#9 by Alex Ruiz on February 4, 2010 - 8:08 pm
@RunsInEDT is simply there for documentation purposes. While working on FEST, I found it pretty difficult to know which method is being ran in the EDT and which on the current thread. I use the annotation just as a reminder of which methods/classes are EDT-safe.
#10 by Luke Nezda on February 4, 2010 - 8:06 pm
@BeforeClass requires decorated method be static: sample code here and copy+pasted to http://www.ibm.com/developerworks/java/library/j-swingtest/ should be:
@BeforeClass public static void setUpOnce() {
FailOnThreadViolationRepaintManager.install();
}
#11 by Alex Ruiz on February 4, 2010 - 8:11 pm
I apologize for the confusion. I’m a TestNG user and it doesn’t require the @BeforeClass method to be static. I should have specified that.
Thanks!
#12 by Jimmy on July 3, 2010 - 10:01 pm
[Sorry for the duplicate comment, I misspelled my email address in earlier one]
Hi Alex,
I was so glad to find an article which talks about writing EDT safe swing tests. This is exactly the challenge that I am facing currently. Unfortunately, I am not using FEST, so the methods described here does not solve my problem. I would appreciate if you could help me in understanding what I am doing wrong in my test.
Here is what I have in my JUnit test:
@Test
public void testSomething()
{
// Line 1: do something
// Line 2: Execute code which generates mouseDragged event
// Line 3: Verification that mouseDragged event is generated
}
What I notice is that my Line 3 gets executed before the mouseDragged method (which does get executed but little late). I tried adding my verification code on to EDT by wrapping it in InvokeAndWait but it still does not help.
In general I am looking for some basic guidelines on what is the best way to avoid such situation. What exactly should be wrapped in InvokeAndWait and what should not in testing?
Any help is much appreciated.
- Jimmy
#13 by Alex Ruiz on July 4, 2010 - 8:35 pm
I have found that “invokeAndWait” can create deadlocks in test code. I haven’t looked into in detail since FEST offers similar behavior without that limitation.
The trick is to execute line #2 in the EDT and wait till all the events in the EDT has been consumed before executing the code in #3.
How to do it will take probably more than one post to explain. I’d suggest you to fork the code in FEST, especifically the org.fest.swing.edt package. Don’t worry about license, it is Apache 2.0, which is business friendly :)
Cheers,