Custom Metatags and slicker unit tests in Flex

I’m a fan of unit tests. And, although I probably wouldn’t blazen it across my chest like some, I am sold of the benefits.

However, coming from .NET, I miss quite a bit of the elegance present in NUnit when working with FlexUnit.

Most specifically, the setup of a test suite is kinda clunky.

Normally, you have several classes of unit tests, each which have a static suite() method, returning a test suite comprising the unit tests in that class.

Check out the following example:



 public static function suite():TestSuite {

    	var ts:TestSuite = new TestSuite();	   	ts.addTest( new MyTestClass("testMethodA") );

    	ts.addTest( new MyTestClass("testMethodB") );

    	ts.addTest( new MyTestClass("testMethodC") );

    	ts.addTest( new MyTestClass("testMethodD") );

    	return ts;

 }

As you can appreciate, it doesn’t take long for this to get long and clunky. Also, maintanence is a pain in the butt — adding tests don’t get run if you forget to add it in the Suite method, changing names causes RTE, etc etc etc.

In NUnit (and, presumably JUnit), you just decorate a class with [TestFixture], and a method with [Test], and NUnit takes care of the rest using that groovy cat, Reflection.

Luckily for us, Flex gives us the ability to tell the compiler to retain custom metatags in Flex 3. This means we can achieve similar functionailty — at least at the method level.

The first step is to set the compiler option. In Flex Builder 3, right click your project, hop into Flex Compiler, and add this to the list of compiler options:

-keep-as3-metadata+=Test

Then, using flash.utils.describeType() we can find any methods within a class that are decoared with our [Test] method.

The following method examines a class, and returns a TestSuite which contains a test for each decorated method.

        /**

         * Generates a test suite with all the methods in a class decorated with [Test] metadata

         * @param clazz

         * @return

         *

         */

        public static function fromClass(clazz:Class):TestSuite {

            var suite:TestSuite = new TestSuite();

            var testMethodNames : XMLList = describeType(clazz).method.(metadata.(@name==”Test”)).@name

            for each (var node:XML in testMethods) {

                    var methodName:String = node.value()

                    var test:Test = new clazz(methodName);

                    suite.addTest(test);

            }

            return suite;

        }

Personally, I chose to add this to the TestSuite class in FlexUnit, though you may prefer a seperate util class.

Now, getting all the tests for a class is as simple as:

var suite:TestSuite = TestSuite.forClass(myClass);

Much more readable!

Comments welcomed.

Marty

Update : I modified the disvoery method to use the E4X expression suggested by Theo. I must’ve been having a brain-fart at the time, as I’m a huge fan of the E4X syntax. Nice spotting Theo!

Advertisements
Tagged , ,

3 thoughts on “Custom Metatags and slicker unit tests in Flex

  1. Theo says:

    You can simplify your test-discovery-code by using this E4X expression:

    var testMethodNames : XMLList = describeType(clazz).method.(metadata.(@name==”Test”)).@name

    That is, instead of iterating over all nodes with metadata, you select the data you want in the expression.

    You can see an example of this at the bottom of this post: http://blog.iconara.net/2008/03/18/creating-specialized-compilers-with-the-flex-compiler-api/

    Otherwise, I totally agree with you that this is a good way to use metadata tags.

  2. Somehow i missed the point. Probably lost in translation 🙂 Anyway … nice blog to visit.

    cheers, Antivivisection.

  3. janekcani says:

    Have a look at http://code.google.com/p/fluint/
    It has this functionality built in. It also offers some extensions to FlexUnit, such as async test environment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: