FlexUnit UI factory

When I started looking into how we could use flexunit in our CI build, I was struck by how the UI is closely linked to the actual running of the test suite. I really wanted to be able to use the supplied flexunit GUI out of the box – after all, it does everything the developer needs, and yet in order to have the results understood by our build process, we would need the results printed out differently.

To acheive this, my Flexunit test harness uses a factory method pattern to decide how torunthe test suite. Here’s how…

I first started by taking the skeleton flexunit testsuite implementation outlined by Darron Schall here. Next, I removed the testRunner MXML node, and changed my creationComplete function to look like this:

private function onCreationComplete():void{
	var testRunner:IFlexUnitUI = FlexUnitUIFactory.createUI();
	var visualTR:UIComponent = testRunner as UIComponent;
	addChild(visualTR)
	visualTR.percentWidth = 100;
	visualTR.percentHeight = 100;
	testRunner.setTest(createSuite());
	testRunner.startTest();
}

OK, so far this doesnt really tell you guys much, so lets delve a little deeper into whats going on… my test runner satisfies an interface that simply allows me to set a test and start a test. This decouples the way we run our tests (and display our results) from the main testHarness. The flexUnitUIFactory
is a very simple interface:

package com.fmr.flexunit
{
	import flexunit.framework.TestSuite;
	public interface IFlexUnitUI
	{
		function setTest(t:TestSuite):void;
		function startTest():void;
	}
}

Now, lets look at the factory itself:

package com.fmr.flexunit
{
	import flash.system.Capabilities;
	//creates an IFlexUnit UI for use by the test harness.
	// the idea is that one can have either visual feedback, or a lightweight text feedback, depending on requirements
	public class FlexUnitUIFactory
	{
		public static function createUI():IFlexUnitUI{
		var environment:String = Capabilities.playerType;
		var outObj:IFlexUnitUI;
		switch(environment){
			case "StandAlone":
				outObj = new TextOutputUI();
				break;
			case "PlugIn":
			default:
				outObj = new FlexUnitUI();
				break;
			}
			return outObj;
		}
	}
}

The factory is actually very simple – it chooses a TextOutputUI if its running in a standalone player (and thus being run as an ANT build), or uses a pretty GUI if in the browser (thus being run by the developer). Each of these UI’s must satisfy our interface, and so I needed to subclass the flexunit GUI to get it to satisfy the interface:

package com.fmr.flexunit
{
	import flexunit.flexui.TestRunnerBase;
	import flash.events.Event;
	import flexunit.framework.TestSuite;
	public class FlexUnitUI extends TestRunnerBase implements IFlexUnitUI
	{
		public static var testsCompleteEvent:String = "testsComplete";
		override public function onAllTestsEnd() : void {
			super.onAllTestsEnd();
			dispatchEvent(new Event(testsCompleteEvent));
		}
		public function setTest(t:TestSuite):void{
			test = t;
		}
	}
}

The TextOutputUI uses our CruiseControl friendly outputting classes, and is simply a VBox (as we need our elememnt to be a IUObject that can be atached to our main app):

<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" implements="com.fmr.flexunit.IFlexUnitUI">
<mx:Script>
<![CDATA[
	import flexunit.framework.TestSuite;
	import flexunit.textui.TestRunner;
	public var test:TestSuite;
	public function setTest(t:TestSuite):void{
		test = t
	}
	public function startTest():void{
		CruiseControlTestRunner.run( test, onTestsComplete );
	}
	private function onTestsComplete():void{
		fscommand("quit");
	}
]]>
</mx:Script>
</mx:VBox>

Notice also that in our textOutputUI, when the tests are complete, the app is told to quit – this is a requirement of our ANT build process as once the unit tests are run, the main app should be built.

And that’s basically it. Using this method, our test harness can run differently depending on its environment. I havent had a chance to test this in the field yet, but I’ll let you know how it all works out…

This entry was posted in Flash & Actionscript, Test Driven Development. Bookmark the permalink. Comments are closed, but you can leave a trackback: Trackback URL.