Timeout and/or Async problems with Flex Unit
Hi all.
I'm currently working on a Flex project at work. We're doing some very simple unit tests. I'm pretty sure that we're using Beta 2. (Annoyingly, I've had this problem for a couple of months, and I've just checked and RC1 has been released!)
They're all controlled by a central MXML application whose onCreationComplete method is a creation of a FlexUnitCore, addition of UI listeners, and then a core.run, listing all of our tests.
var core:FlexUnitCore = new FlexUnitCore();
core.addListener(new UIListener(uiListener));
core.addListener(new CIListener());
core.addListener(TextListener.getDefaultTextListener(LogEventLevel.DEBUG));
core.addEventListener(Event.DEACTIVATE, finished);
core.run(ClosableDockPanelTest,
DockHBoxTest,
DockHDividedBoxTest,
DockVBoxTest,
DockVDividedBoxTest,
EffectsTest,
ShadedHeaderTest,
StandardHeaderTest,
SlidingPanelTest,
etc etc
One of the tests (for example) is a login form test. The login form is a simple group of nested MXML components, giving an attractive header, a login warning, username and password box. All very simple. There's no script in it at all, it's pure MXML.
The test script is all Actionscript. Below is a snippet...
public class LoginFormTest
{
private var loginForm:LoginForm;
[Before(async, ui, timeout="20000")]
/**
* Test setup.
*/
public function setUp():void
{
loginForm = new LoginForm();
Async.proceedOnEvent(this, loginForm, FlexEvent.CREATION_COMPLETE);
UIImpersonator.addChild(loginForm);
}
[Test]
/**
* Checks to make sure there is no text in the login text
*/
public function testCreatedOK():void
{
assertThat("Login form is null", loginForm, notNullValue());
assertThat("Username label text is not blank", loginForm.userLabel.text, equalTo(""));
assertThat("Password label text is not blank", loginForm.passLabel.text, equalTo(""));
}
...
More test cases
....
As part of our CI, this MXML Unit test application is compiled and run from an ANT script.
On my dev machine, it all works perfectly. Time after time, the app compiles and runs with no failures.
As soon as we put it on the CI machine (and one of the other dev machines), it will fail about 50% of the time Bear in mind there are many tests like this, so any one test won't fail 50% of the time, but 50% of the time, one of the 50 or so tests will fail once.
The cause of the failure is a timeout before an event happened. As far as I can tell, one of two things isn't happening.
1) The creation complete event doesn't always fire
2) The timeout property in the metadata is ignored. It doesn't matter what value it's set to, when there's a timeout failure, the time between the test starting and failing is instant, it's certainly not waiting 20 seconds for the event. Alternatively, setting it to a small number never causes any more failures due to timeouts.
I'm getting around this (temporarily) by not triggering on the FlexEvent.CREATION_COMPLETE event. Instead, I start a local timer, and wait for the TIMER_COMPLETE event before I continue.
This now works far more reliably, but still occasionally fails.
This is not really what I want though. I need the tests to work properly, and trigger on the events that I know are there!
Does anyone have any ideas of how to improve the tests.
I'm guessing that I might want to try one or more of the following...
1) Make the creation of the login form local to each test case
2) Make the creation of the login form only once in a BeforeClass (ISTR) method, and then tear it down in an AfterClass, rather than doing it in a Before method.
3) Is it likely that this is a manifestation of Beta 2 FXU-66 "regarding timing with async listeners" which is now fixed in RC1?
Before I start making changes to them, putting them on the CI server, and waiting 10 minutes to find out if there's been a failure, I thought it would be handy if someone could say "Oi! Muppet! You're doing it wrong! Do it like this!".
Thanks.
Pete.
