FlexUnit with AIR & Ant

Since last week FlexUnit has a new home on Adobe Open Source and I thought it would be the time to finalize my post about FlexUnit with AIR and Ant which I had in the pipe for a longer time.

You can run Ant via command line or from within Eclipse which provides an Ant panel if you use Flex Builder plugin version. If you are using Flex Builder standalone check this article about how to install Ant it afterwards.

You have to download Peter Martin’s JUnitTestRunner class which was build to test within the Flash Player and not AIR so it uses XMLSocket to hand over the test result. AIR has the capability to write directly to the users hard drive so we will add this functionality by subclassing JUnitTestRunner.

Download the AIRAntUnitTest project and import it into Flex Builder.

You will get four errors because Peter Martin’s JUnitTestRunner class is not delivered in my zip. So please download it from his blog (last Donwload link at the end of his post) and add it to the directory flexunit/junit.

You have to change the JUnitTestRunner class slightly to make my subclass work:

  • Change the following member variables from private to protected: reports, totalTestCount, numTestsRun
  • Change the createXMLReport method modifier from private to protected

Now the project should build without errors.

Change the build.xml and enter the path to your installed Flex SDK by defining the property flex.sdk.dir (in my case D:/tools/flex_sdk_3.0.2.2113).

Your setup is complete and now you have two options to launch you unit tests:

The first option is to use the visual runner of the FlexUnit project. Right-click the AIRAntUnitTest.mxml and choose Run As->Adobe AIR Application. This launches the debug launcher and since no parameter is passed the visual runner get’s the test suite and is started (onInvoke event listener). The result should look like this:

FlexUnit TestRunner

The second option is to use Ant. If you want to launch it from within Eclipse open the Ant panel (Window->Show View->Other->Ant->Ant). Now drag the build.xml from the AIRAntUnitTest project into this panel and it should look like this:

Ant Panel

Here you see the five different Ant targets. The build target is default and calls clean, compile, run-tests and generate-reports. Double-click “build” to run the tests.

  • clean removes the bin-release and reports directory
  • compile compiles the SWF for AIR
  • run-tests opens the AIR application in the debug player (ADL) which get’s closed with exit code 0 if all tests passed and 1 if there were failures or errors
  • generate-reports uses the junitreport feature of Ant and handles the xml results generated by Peter’s JUnitTestRunner and written to hard disk with the AIR file API

The generated reports look like this:

Unit Test Results

If you want your build to fail when failures or errors come up change the attribute failonerror to “true” in the run-tests target.

With this approach you could run your unit tests automatically on your build server and do Continous Integration so you would have a self-testing build.

Many thanks to Peter Martin for his JUnitTestRunner and I hope this AIR approach is usefull for some of you guys.

14 comments to FlexUnit with AIR & Ant

  • Trung

    Does this approach work with the CI server which is in Linux (no UI)? Or we still have to create xorg buffer to host the AIR app?

  • Trung, so far as I know this cannot be run headless.

  • Hi,

    Thanks for this, but I have a niggle…

    For the life of me I can’t figure out why this keeps occuring, I googled around and tried setting nativePath, using URL syntac and also placing the project in a path with no spaces, but I cant get rid off this error:

    Error: Invalid output directory: [object File], flexunit
    at flexunit.junit::JUnitTestRunnerAIR/start()[C:\temp\AIRAntUnitTest\src\flexunit\junit\JUnitTestRunnerAIR.as:39]
    at AIRAntUnitTest/onInvoke()[C:\temp\AIRAntUnitTest\src\AIRAntUnitTest.mxml:33]
    at AIRAntUnitTest/___AIRAntUnitTest_WindowedApplication1_invoke()[C:\temp\AIRAntUnitTest\src\AIRAntUnitTest.mxml:3]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()[E:\dev\3.0.x\frameworks\projects\framework\src\mx\core\UIComponent.as:9051]
    at mx.core::WindowedApplication/dispatchPendingInvokes()[E:\dev\3.0.x\frameworks\projects\airframework\src\mx\core\WindowedApplication.as:2540]
    at mx.core::WindowedApplication/enterFrameHandler()[E:\dev\3.0.x\frameworks\projects\airframework\src\mx\core\WindowedApplication.as:2526]

    Launched using:
    C:\wk\apps\flex_sdk_3\bin\adl build/air/AIRAntUnitTest-app.xml — \temp\flexunit

    as when launch as ant task gives less help:

    C:\temp\AIRAntUnitTest>ant
    Buildfile: build.xml

    clean:
    [delete] Deleting directory C:\temp\AIRAntUnitTest\build\air
    [delete] Deleting directory C:\temp\flexunit

    compile:
    [mxmlc] Loading configuration file C:\wk\apps\flex_sdk_3\frameworks\air-config.xml
    [mxmlc] C:\temp\AIRAntUnitTest\build\air\AIRAntUnitTest.swf (767526 bytes)

    run-tests:
    [mkdir] Created dir: C:\temp\flexunit
    [echo] Test descriptor build/air/AIRAntUnitTest-app.xml with ADL C:\wk\apps\flex_sdk_3\bin\adl and content AIRAntUnitTest.swf
    [copy] Copying 1 file to C:\temp\AIRAntUnitTest\build\air

    BUILD FAILED
    C:\temp\AIRAntUnitTest\build.xml:72: Execute failed: java.io.IOException: CreateProcess: C:\wk\apps\flex_sdk_3\bin\adl build/air/AIRAntUnitTest-app.xml — \temp\flexunit
    error=193

  • Hi,

    Im new to Air, but after a bit more investigation, and a fresh new day, I found that there were 2 problems:

    1. the Air code needed to resovle the directory,
    2. The ANT script was not finding ADL.exe on windows

    for #1:

    I changed AIRAntUnitTEst.mxml ‘onInvoke’ method to be:
    runner.start(createSuite(), event.currentDirectory.resolvePath(outputDirPath));

    I’m not convinced this is the ideal solution…
    It is important, when not using relative paths to the current working directory, to pass drive letters when paths that start with a \, as they do not seem to be valid.

    For #2:
    The win32 process could not be found as the ADL property wasn’t being set to …\adl.exe, so I altered the set ant task logic:

    hope that helps
    Regards
    Wayne

  • Wayne,
    you are calling adl via command line and the example uses {basedir}/reports as the output directory which should work fine. When you want to specify an abolsute dir you sould use “/” instead of backslash.

    to #2: the os is handled by ant so this part of the build script should handle the link to adl:

  • Hi,

    #1 I was calling it directly whilst trouble shooting. I dint want an abolute dir and it failed to work without that addtional code I put it, it appears to truncate the path to all but the leafnode/dir. I tried variaous combinations of path separator, I will revist.

    #2 Ant would not set the ‘ADL’ variable to …/ADL.exe for reasons I just can not explain, I also tried os family=’winnt’, however it would not work. Hence my change.

  • to #1: but when can use a reletive dir with the ant variable {basedir} or what am I missing?

    to #2: I will check this when I have time again but at I am glad you were able to solve it.

  • HI,

    #1 here I must apologies and explain that I have deviated from the shipped build.xml . I am using a properties file that defines the reports.dir using a location with no reference to the ${basedir}

    e.g. effetively, as it’s actually built up of other props, in build/properties ultimately ends up being:

    reports.dir=dist/docs/reports

    I assume then that ${basedir} expands to the fully qualified native path, so perhaps I should have done that. Although what I am tryin isn’t unusual, I thought.

    Regards
    Wayne

  • thanks for putting this together it was exactly what I was looking for. the ant script and test application are both easy to understand for me. I am not much of a ANT or unit testing guru.

  • Peter

    Sonke, thanks for putting this together and sharing.

    I was trying to figure out if there’s a way to quit the ADL with ant, don’t suppose you could comment? (Using a mac, thinking maybe have to use it in conjunction with applescript somehow?)

  • Peter, I think I don’t get what you want to achieve. What would be the usecase for this?

  • Peter

    I’m running an ant build from eclipse that launches the ADL, if I run it when the ADL is still running it fails. It’s just a little annoyance that if I could fix I would.

  • Now I got it but I think this is really nice to have. just but cmd+q and the app is closed and flex unit tests could exit automatically.

  • Gary

    Hi Sonke

    thansk for the post and sharing, ive been trying to get hold of Peters flexunit stuff with no luck all the links i try seem to be broken

    do you know where i can get ti from? im new to all of this so im learning as i go

    Kind Regards