AS3Unit (日本語はこちら)

Source Code / License / Documentation / ASDoc

Documentation for AS3Unit

AS3Unit is a Unit Test framework for ActionScript? 3.0. By leveraging a namespace feature, which is introduced in AS3, you can write your unit test in POJO style.

AS3Unit enables you to develop Flash application efficiently in test-driven style.

This document is not completed. Please refer ASDoc for detailed specifications.

Make a Test

Test class

In AS3Unit, you don't have to inherit specific class nor implement specific interface. You have only to make a public class.

public class SampleTest
{
}

How the test methods are invoked by AS3Unit

You need to modify test methods by "test" namespace. Then the modified methods are invoked by AS3Unit.

The test method must not take any arguments and must return void. You don't need to care about the name of methods. Please don't forget to write "use namespace test" in your source code.

import org.libspark.as3unit.test;

use namespace test;

public class SampleTest
{
    test function sample1():void
    {
    }
    
    test function sample2():void
    {
    }
}

Asserts

Asserts methods are packaged in org.libspark.as3unit.assert. Import "org.libspark.as3unit.assert" and use them like as follows:

import org.libspark.as3unit.test;
import org.libspark.as3unit.assert.*;

use namespace test;

public class SampleTest
{
    test function sample1():void
    {
        var s:Sample = new Sample();
        assertTrue(s.f());
    }
    
    test function sample2():void
    {
        var s:Sample = new Sample();
        assertEquals("hello", s.h());
    }
}

"before" namespace

If you modify a method by "before" namespace, the modified method is always invoked before each test runs. So "before" namespace is useful to prepare stuffs that are needed by test method.

import org.libspark.as3unit.test;
import org.libspark.as3unit.before;
import org.libspark.as3unit.assert.*;

use namespace test;
use namespace before;

public class SampleTest
{
    private var s:Sample;
    
    before function setupSample():void
    {
        s = new Sample();
    }
    
    test function sample1():void
    {
        assertTrue(s.f());
    }
    
    test function sample2():void
    {
        assertEquals("hello", s.h());
    }
}

"after" namespace

If you modify a method by "after" namespace, the modified method is always invoked after each test runs. So "after" namespace is useful to clean up stuffs that are needed by test method.

import org.libspark.as3unit.test;
import org.libspark.as3unit.before;
import org.libspark.as3unit.after;
import org.libspark.as3unit.assert.*;

use namespace test;
use namespace before;
use namespace after;

public class SampleTest
{
    private var s:Sample;
    
    before function setupSample():void
    {
        s = new Sample();
    }
    
    after function teardownSample():void
    {
        s.finalize();
    }
    
    test function sample1():void
    {
        assertTrue(s.f());
    }
    
    test function sample2():void
    {
        assertEquals("hello", s.h());
    }
}

"beforeClass" namespace

If you modify a method by "beforeClass" namespace, the modified method is invoked once before the any test method in the class runs.

"afterClass" namespace

If you modify a method by "afterClass" namespace, the modified method is invoked once after all test method in the class runs.

"test_expected" namespace

If you want to test whether a specific error is thrown in a method, create static and const property, and modify the property by "test_expected" namespace, and assaign a expected error class to the property. The name of property must be same to the name of a method.

import org.libspark.as3unit.test;
import org.libspark.as3unit.test_expected;

use namespace test;
use namespace test_expected;

public class SampleTest
{
    // ArgumentError is expected to thrown in error() method
    test_expected static const error:Class = ArgumentError;
    test function error():void
    {
        var s:Sample = new Sample();
        s.e(null);
    }
}

Test Suite

Test Suite is useful when you want to run more than two test classes. To make Test Suite, please enumerate the classes that you want to run in SuiteClasses? array.

import org.libspark.as3unit.runners.Suite;

public class AllTests
{
    public static const RunWith:Class = Suite;
    public static const SuiteClasses:Array = [
        SampleTest,
        HogeTest,
        FugaTest
    ];
}

Test Suite is nestable.

To run a test

Easy way to run a test is to use AS3UnitCore class. Invoke "main" method of AS3UnitCore class with passwing Test Class or Test Suite as an argument. Then the result is shown in "trace" console.

import org.libspark.as3unit.runner.AS3UnitCore;

...

AS3UnitCore.main(AllTests);

Writing test for asynchronous method

You can write test for asynchronous method by using ASUnit for Async.

To write a test for asynchronous method, use org.libspark.as3unit.assert.async method. This async() method takes an function and time-limit as an its argument and return checkpoint function.

To pass a test, invoke a returned checkpoint function within the time-limit that is passed as an second argument for asyc() method.

A function that is passed as an argument for async() method is automatically invoked when a checkpoint function is invoked. So you can write assertion test in the function.

The below example shows how to test a Timer class. This test checks if TimerEvent?.TIMER event occurs specified times before TimerEvent?.TIMER_COMPLETE event occurs.

import org.libspark.as3unit.test;
import org.libspark.as3unit.assert.*;
import flash.utils.Timer;
import flash.events.TimerEvent;

use namespace test;

public class TimerTest
{
    test function timer():void
    {
    	var count:uint = 0;
    	var timer:Timer = new Timer(10, 3);
    	timer.addEventListener(TimerEvent.TIMER, function(e:TimerEvent):void
    	{
    		count++;
    	});
    	timer.addEventListener(TimerEvent.TIMER_COMPLETE, async(function(e:TimerEvent):void
    	{
    		timer.stop();
    		assertEquals(3, count);
    	}, 1000));
    	timer.start();
    }
}

Important point for this example is below. You'll see that checkpoint function is registered as TimerEvent?.TIMER_COMPLETE event-listener. By doing this, this asynchronous test is passed successfully. ", 1000" means time-limit in milli-seconds, so if the checkpoint function is not invoked within 1000 milli-seconds, the test fails and return TimeoutError?. In checkpoint function, use assertEquals() function to check whether time timer event occurred specified time.

timer.addEventListener(TimerEvent.TIMER_COMPLETE, async(function(e:TimerEvent):void
{
	timer.stop();
	assertEquals(3, count);
}, 1000));

If you have a time, please have a look at AsyncTest class, which is a test case fot AS3Unit itself.