Continuous Integration with Flex 3, CruiseControl.rb and FlexUnit4

May 23rd, 2009

Finally an easy actionscript CI set up!
Here are the steps I went through to get CruiseControl.rb up and funning for a flex project.

The basic concept is to create an air app along side your flex project that will run all the unit tests. CruiseControl.rb will then checkout all the code, build and run the air app then report what happened.

All of the files for this tutorial can be downloaded here (libs not included):
Flex-CCrb.zip

Stuff you need:
A subversion repository to store your project.
CruiseControl.rb
Flex SDK
Ant
FlexUnit 4 (Currently in alpha)

1. Download above software
2. install ant
3. Put the flex sdk here: /Developer/adobe/sdk/
4. Create a directory to hold a new flex project or create a new project with flex builder.(name it what you like)
5. Create a source directory called “src” in your project directory. (done for you with flex builder)
6. Create a library directory called “libs” in your project directory. (done for you with flex builder)
7. Add all of the FlexUnit4 swc files you downloaded above to the libs directory.
8. Create an mxml file called FlexUnit4AirRunner.mxml in the src directory.
9. Add this code to FlexUnit4AirRunner.mxml:

< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="runMe()" implements="org.flexunit.runner.notification.IRunListener">
	</mx><mx :Script>
		< ![CDATA[
			import org.flexunit.runner.notification.IRunListener;
			import org.flexunit.listeners.UIListener;
			import org.flexunit.runner.Request;
			import org.flexunit.runner.FlexUnitCore;
			import flash.desktop.NativeApplication;
			import org.flexunit.runner.IDescription;
			import org.flexunit.runner.Result;
			import org.flexunit.runner.notification.Failure;
			import org.flexunit.runner.notification.IRunListener;
 
 
			private var core:FlexUnitCore;
			private var failureDidOccure:Boolean = false;
 
			public function runMe():void
			{
				core = new FlexUnitCore();
				core.addListener(this);
				core.run(  SampleTestSuite  );
			}
 
			public function testRunStarted( description:IDescription ):void
			{
			}
 
			public function testRunFinished( result:Result ):void
			{
				var errorNum:int = 0;
				if(failureDidOccure)
					errorNum = 1;
 
				NativeApplication.nativeApplication.exit(errorNum);
			}
 
			public function testStarted( description:IDescription ):void
			{
			}
 
			public function testFinished( description:IDescription ):void
			{
			}
 
			public function testFailure( failure:Failure ):void
			{
				failureDidOccure = true;
				trace("TEST FAILURE: " + failure.description.displayName);
				trace(failure.message);
			}
 
			public function testAssumptionFailure( failure:Failure ):void
			{
			}
 
			public function testIgnored( description:IDescription ):void
			{
			}
		]]>
	</mx>

10. Create an actionscript file called SampleTestSuite.as in the src directory.
11. Add this code to SampleTestSuite.as

package
{
	[Suite]
	[RunWith("org.flexunit.runners.Suite")]
	public class SampleTestSuite
	{
		public var sampleTest:SampleTest;
	}
 
}

12. Create a actionscript file called SampleTest.as in the src directory.
13. Add this code to SampleTest.as

package
{
	import org.flexunit.Assert;
	import org.flexunit.assertThat;
	import org.hamcrest.collection.hasItems;
	import org.hamcrest.number.greaterThan;
 
 
	public class SampleTest
	{
		[Test]  
		public function testUpdate():void
		{   
		    Assert.assertTrue(true);
		}
	}
}

14. Create an app descriptor file called “FlexUnit4AirRunner-app.xml” in the src directory.
15. Add this xml to “FlexUnit4AirRunner-app.xml”

< ?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://ns.adobe.com/air/application/1.5">
	<id>FlexUnit4AirRunner</id>
	<filename>FlexUnit4AirRunner</filename>
	<name>FlexUnit4AirRunner</name>
	<version>v1</version>
	<initialwindow>
		<content>FlexUnit4AirRunner.swf</content>
	</initialwindow>
</application>

16. Create an ant build file called “build.xml” and put it in the root of your project directory
17. Add this to the ant build file. (you may need to edit the paths depending on your flex sdk version)

<project basedir="./src">
	<target name="CCBuild">
	    	<exec failonerror="true" executable="/Developer/adobe/sdk/3.2.0/bin/amxmlc">
	    	   	<arg line="FlexUnit4AirRunner.mxml -output FlexUnit4AirRunner.swf" />
	    		<arg line="-compiler.locale=en_GB,en_US" />
	    		<arg line="-compiler.library-path  ../libs" />
	    		<arg line="-compiler.library-path  /Developer/adobe/sdk/3.2.0/frameworks/locale/en_US" />
	    		<arg line="-compiler.library-path  /Developer/adobe/sdk/3.2.0/frameworks/libs" />
	    		<arg line="-compiler.library-path  /Developer/adobe/sdk/3.2.0/frameworks/libs/air" />
	    		<arg line="-compiler.library-path  /Developer/adobe/sdk/3.2.0/frameworks/libs/2.0.1.automation_swcs" />
	    		<arg line="-compiler.library-path  /Developer/adobe/sdk/3.2.0/frameworks/libs/player" />
	    	</exec>
 
	    	<exec failonerror="true" executable="/Developer/adobe/sdk/3.2.0/bin/adl">
				<arg line="FlexUnit4AirRunner-app.xml" />
			</exec>
	    </target>
</project>

18. Check all this into an svn repository
19. Open terminal and head to the CruiseControl.rb directory you downloaded in step 1.
20. type this command but replace the “ProjectName” and url with real stuff.

cruise add ProjectName -u "http://url.of.the.svn.repoitory.you/just/created"

21. Open up the following file in a text editor: ~/.cruise/projects/ProjectName/cruise_config.rb
22. Right below this line “Project.configure do |project|” add this:

project.build_command = 'ant CCBuild'

23. Go back to the main CruiseControl.rb directory
24. Type this command

cruise start

25. Click here: http://localhost:3333
26. Your Done! You should see CCrb up and running and a built project with no errors. Try changing the assert in SampleTest.as to false, then checkin your code. Next, force a rebuild at http://localhost:3333 and you should see a failed build.

4 Responses to “Continuous Integration with Flex 3, CruiseControl.rb and FlexUnit4”

  1. Ivan Said:

    Nice man! Very helpful.. thanks

  2. Aaron Spjut » Blog Archive » Continuous Integration with Flex 2 (Actionscript 3), FlexUnit, CruiseControl, Apollo and subversion on OS X Said:

    [...] I’ve created a newer tutorial using CruiseControl.rb. IMO Its a better [...]

  3. ARnoud Bos Said:

    Hi,

    This is a nice tutorial, but if i try it (with hudson) i don’t get the reporting.
    Do you have the same or do you get the flexunit reports output?

    thanx,

    Arnoud

  4. Aaron Spjut Said:

    ARnound:
    Thanks for the comment. Your right there was no output of the tests in this example. I’ve updated the testFailure method of FlexUnit4AirRunner.mxml above to print the failed tests. Basically you can trace any thing you want in the different handler methods and it will show up in the reporting. This is true for CC anyway, I haven’t tried Hudson.

Leave a Reply