I wrote a simple UI automation test for my application using Project White. It just launches the app and checks if the main window exists. This is done in the context of an NUnit test:
///AppTest.cs
[Test]
public void ShouldDisplayMainForm() {
using( var wrapper = new WhiteWrapper( MYAPP_PATH ) ){
Window win = wrapper.GetWindow( "MYAPP_MAIN_FORM_TITLE" );
Assert.IsNotNull(win);
}
}
///WhiteWrapper.cs
using System;
using White.Core;
using White.Core.Factory;
using White.Core.UIItems;
using White.Core.UIItems.WindowItems;
namespace MGClient.Test {
internal class WhiteWrapper : IDisposable {
private readonly Application mHost;
private readonly Window mMainWindow;
public WhiteWrapper( string pPath ) {
mHost = Application.Launch( pPath );
}
public WhiteWrapper( string pPath, string pMainWindowTitle )
: this( pPath ) {
mMainWindow = GetWindow( pMainWindowTitle );
}
public void Dispose() {
if( mHost != null )
mHost.Kill();
}
public Window GetWindow( string pTitle ) {
return mHost.GetWindow( pTitle, InitializeOption.NoCache );
}
public TControl GetControl<TControl>( string pControlName ) where TControl : UIItem {
return mMainWindow.Get<TControl>( pControlName );
}
}
}
The problem is that the test results are random: sometimes it fails, sometimes it succeeds, without following a pattern.
The test environment is set so that initialization fails: I want to see the test fail consistently. The problem is that my app's main form performs its initialization and all related validations in the handler for its Load
event. I think there is a race condition, due to the fact that White runs the application under test in a separate process:
When GetWindow
is called before the initialization failure is detected, the test succeeds. When failure detection wins the race, it closes the app, so this makes GetWindow
fail.
I'm looking through White documentation and browsing through samples, but I can't find a workaround for this scenario. Changing the app's code should be a last resort since I don't have a test harness yet (and that's what got me stuck: all my ideas revolve around changing the app).
I looked at White.Core.UIItems.WindowItems.Window
's public interface and found the WaitTill
method, which paired with the IsCurrentlyActive
property did the trick:
///AppTest.cs
[Test]
public void ShouldDisplayMainForm() {
using( var wrapper = new WhiteWrapper( MYAPP_PATH ) ){
Window win = wrapper.GetWindow( "MYAPP_MAIN_FORM_TITLE" );
Assert.IsNotNull(win);
win.WaitTill( ()=> win.IsCurrentlyActive );
}
}
Now the test always fails. Sometimes it times out in the GetWindow
call, sometimes it does in WaitTill
. But it always fails when initialization does, so that's good enough for me.
To other White noobs: documentation is pretty scarce, so bear with it and look at the source (if you find some good doc source, please do tell).