Flash Builder 4 Feature – Unit Tests

Flash Builder 4 is really cool, I want to start by saying that. With the new features available in Flash Builder 4 applications will only be coming out faster with higher levels of quality. One of my favorite additions is built in Unit Testing framework into Flash Builder 4.
picture-2

Flash Builder 4 has FlexUnit built right into the framework, and as such there are some new helpers to simplify the creation of Unit Tests directly within Flash Builder. We are going to start this post with creating a new Flex Project. We are going to create a new ActionScript (AS) File with a few different function. The AS file is included below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.unitedmindset.controllers
{
    public class ProductController
    {
        public function ProductController()
        {
        }
       
        private var _taxRate:Number = 0.0825;
       
        public function addTax(cost:Number):Number
        {
            return cost*_taxRate;
        }
       
        public function get taxRate():Number
        {
            return _taxRate;
        }
       
        public function set taxRate(value:Number):void
        {
            if(value<1)
                _taxRate = value;
            else
                _taxRate = 1;
            if(value<0)
                _taxRate = 0;
        }
       
    }
}

Now, time for the new stuff. We have created our our controller, now we will create our new test case. Using the “new” menu I am going to add a new Test Case with the following options.
"New" Options

New Test Case Options

New Test Case Options


Select Methods Option Window

Select Methods Option Window


These options produce the following code (I love Flash Builder 4):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package flexUnitTests
{
    import com.unitedmindset.controllers.ProductController;
   
    import flexunit.framework.TestCase;
   
    public class ProductControllerTest extends TestCase
    {
        // please note that all test methods should start with 'test' and should be public
       
        // Reference declaration for class to test
        private var classToTestRef : com.unitedmindset.controllers.ProductController;
       
        public function ProductControllerTest(methodName:String=null)
        {
            //TODO: implement function
            super(methodName);
        }
       
        //This method will be called before every test function
        override public function setUp():void
        {
            //TODO: implement function
            super.setUp();
        }
       
        //This method will be called after every test function
        override public function tearDown():void
        {
            //TODO: implement function
            super.tearDown();
        }
       
        public function testAddTax():void
        {
            // Add your test logic here
            fail("Test method Not yet implemented");
        }
       
        public function testProductController():void
        {
            // Add your test logic here
            fail("Test method Not yet implemented");
        }
    }
}

I made some simple changes to the Test Case to check for some of the logic we put into the controller. The changed code looks as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package flexUnitTests
{
    import com.unitedmindset.controllers.ProductController;
   
    import flexunit.framework.Assert;
    import flexunit.framework.TestCase;

    public class ProductControllerTest extends TestCase
    {
        // please note that all test methods should start with 'test' and should be public
        private var controller:ProductController;
       
        // Reference declaration for class to test
        private var classToTestRef : com.unitedmindset.controllers.ProductController;
       
        public function ProductControllerTest(methodName:String=null)
        {
            //TODO: implement function
            super(methodName);
        }
       
        //This method will be called before every test function
        override public function setUp():void
        {
            //TODO: implement function
            super.setUp();
            controller = new ProductController();
        }
       
        //This method will be called after every test function
        override public function tearDown():void
        {
            //TODO: implement function
            super.tearDown();
            controller = null;
        }
       
        public function testAddTax():void
        {
            // Add your test logic here
            var tax:Number = controller.taxRate;
            var productCost:Number = 14.99;
            var total:Number = (1+tax)*productCost;
            var testTotal:Number = controller.addTax(productCost);
            assertEquals(total,testTotal);
        }
       
        public function testSetTaxRateLowerThanZero():void
        {
            controller.taxRate = -0.01;
            assertEquals(controller.taxRate,0);
        }
       
        public function testSetTaxRateBetweenZeroAndOne():void
        {
            controller.taxRate = 0.5;
            assertEquals(controller.taxRate,0.5);
        }
       
        public function testSetTaxRateGreaterThanOne():void
        {
            controller.taxRate = 1.01;
            assertEquals(controller.taxRate,1);
        }
       
        public function testProductController():void
        {
            // Add your test logic here
            assertEquals(controller.taxRate,0.0825);
        }
    }
}

Now we need to add a new suite to our testing framework. Again using the “New” menu we Add a new Test Suite with the following settings.

New Test Suite

New Test Suite

Which produces the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package flexUnitTests
{
    import flexUnitTests.ProductControllerTest;
   
    import flexunit.framework.TestSuite;
   
    public class ProductSuite extends TestSuite
    {
        public function ProductSuite(param:Object=null)
        {
            super(param);
        }
       
        // this method shall be called when this suite is selected for running.
        public static function suite():TestSuite
        {
            var newTestSuite:TestSuite = new TestSuite();
            newTestSuite.addTest(new flexUnitTests.ProductControllerTest("testProductController"));
            newTestSuite.addTest(new flexUnitTests.ProductControllerTest("testAddTax"));
            newTestSuite.addTest(new flexUnitTests.ProductControllerTest("testSetTaxRateLowerThanZero"));
            newTestSuite.addTest(new flexUnitTests.ProductControllerTest("testSetTaxRateBetweenZeroAndOne"));
            newTestSuite.addTest(new flexUnitTests.ProductControllerTest("testSetTaxRateGreaterThanOne"));
            return newTestSuite;
        }
    }
}

Something you probably already noticed by now is that Flash Builder 4 has already laid out all of your packages to including the flexUnitTests and the application to run everything titled “flexUnitCompilerApplication”. This file has already had some code placed in it by Flash Builder 4. Making a few small changes we have this application.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="utf-8"?>
<s:Application minHeight="768"
               minWidth="1024"
               xmlns:flexui="flexunit.flexui.*"
               xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:mx="library://ns.adobe.com/flex/halo"
               xmlns:s="library://ns.adobe.com/flex/spark"
               creationComplete="application1_creationCompleteHandler(event)">
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
            import flexUnitTests.ProductSuite;
            import flexUnitTests.ProductControllerTest;
           
            private var flexUnitTests_ProductSuite_obj:flexUnitTests.ProductSuite;
            private var flexUnitTests_ProductControllerTest_obj:flexUnitTests.ProductControllerTest;

            protected function application1_creationCompleteHandler(event:FlexEvent):void
            {
                testRunner.test = ProductSuite.suite();
                testRunner.startTest();
            }

        ]]>
    </fx:Script>
    <flexui:TestRunnerBase id="testRunner"
                           width="100%" height="100%"
                           paddingBottom="20"
                           paddingLeft="20"
                           paddingRight="20"
                           paddingTop="20"/>
</s:Application>

Which looks like the following when we run it.

Our FlexUnit Application

Our FlexUnit Application


Luckily our Test Case did just what we hoped it would, it showed us the flaws in our programming. We can go back now and make changes and rerun our tests to make sure that the application runs as expected. Changing our failing addTax method we get:

1
2
3
4
        public function addTax(cost:Number):Number
        {
            return cost*(1+_taxRate);
        }

Rerunning the application we now have all of our tests passing successfully.

Our Successful Tests

Our Successful Tests

Note: This post has been updated to the Flash Builder 4 Beta Generated Code.

  • Share/Bookmark

Comments (12)

BlahJune 5th, 2009 at 7:56 pm

Hey do you think you can five a tutorial on how to integrate the test into ant (the latest I could find on google was for FB2)? thnx.

Jonathan CamposJune 5th, 2009 at 7:58 pm

That would be a great post, I’ll work it up, thanks for the idea.

Jesse FreemanJune 10th, 2009 at 6:41 pm

Is this possible to do with ANT? I am looking for a way to automate these Unit Tests?

Thanks,
Jesse

Jonathan CamposJune 10th, 2009 at 6:51 pm

You can definitely make this as part of your ant build script. I am preparing the entry this weekend but it was a matter of just pointing your ant to the correct files. I wil have something soon on this.

Jonathan CamposJune 13th, 2009 at 8:18 pm

Jesse,
I’ve been looking into it for a bit and sadly it will take some time to put together. The basic theory is you set up an AIR app > build it and run with ANT > AIR app outputs a File to be read by ANT > ANT reads file with errors/response > TADA! ANT has FlexUnit Results. Though this setup will take a bit. Sounds like a nice long future blog entry.

Jesse FreemanJune 18th, 2009 at 8:02 pm

Yeah I came up with the same conclusion although I think you can bypass having an AIR file and just launch a swf that displays the results. That is what I think Flash Builder is doing now and simply using FP 10′s ability to write to the file system to store the data for Eclipse to read/display in the unit test panel.

I actually don’t care about the output file but just want a basic display of stats from the test. When I get some more free time I am going to try to come up with something but hopefully you will beat me to it ;-)

Thanks for the update,
Jesse

Samuel Asher RivelloJune 21st, 2009 at 11:09 am

This topic looks great. For more Flex 4 and Flash Builder 4 information, see this new course ‘Flex 4 Top 10 Features’ taught by Rivello Multimedia Consulting. Sign up or request it come to your town today! http://www.blog.rivello.org/?p=324

Jonathan CamposJune 30th, 2009 at 2:04 pm

If you get here and want some FB ANT FlexUnit support, vote on this bug in the Adobe Bug base: http://bugs.adobe.com/jira/browse/FB-21128

[...] guys over at Adobe are doing some great work on a major new release of Flex Unit. A new version of Flex Builder is looming around the corner with some very promising unit test integration. There [...]

Jonathan CamposAugust 6th, 2009 at 8:34 am

This just came across my desk and look promising, check it out!
http://www.compactcode.com/index.php/2009/08/unit-testing-and-flex-whats-stopping-you/

[...] http://unitedmindset.com/jonbcampos/2009/06/01/flash-builder-4-feature-unit-tests/ Categories: Adobe Flex, Flex Builder/Flash Builder Tags: ActionScript 3.0, Flex Builder/Flash Builder Comments (0) Trackbacks (0) Leave a comment Trackback [...]

[...] guys over at Adobe are doing some great work on a major new release of Flex Unit. A new version of Flex Builder is looming around the corner with some very promising unit test integration. There [...]

Leave a comment

Your comment