AS3Unit (English is here)

ソースコード / ライセンス / ドキュメント / ASDoc

AS3Unit ドキュメント

AS3UnitはActionScript?3.0上で単体テストを行うためのフレームワークで、JUnit4の移植です。ActionScript?3.0の新機能であるネームスペースを用いる事で、POJOによるテストケースの記述を可能にしました。

AS3Unitを用いる事で、効率よくテスト駆動開発を行うことが出来るようになります。

このドキュメントは書きかけです。ASDocも併せてご覧下さい。

テストの作成

テストクラス

AS3Unitでは、テストクラスは特定のインターフェイスを実装したり、特定のクラスを継承したりする必要はありません。単純なpublicクラスを用意すればOKです。

public class SampleTest
{
}

test

テストメソッドは「test」ネームスペースで修飾します。これで、そのメソッドがテストメソッドとして自動で呼び出されます。

メソッドは引数なし、voidである必要があります。メソッド名は何でも構いません。「use namespace test」を忘れないように。

import org.libspark.as3unit.test;

use namespace test;

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

アサート

お馴染みのアサートは、org.libspark.as3unit.assert以下に関数として用意されています。以下のようにimportして使ってください。

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

「before」ネームスペースで修飾されたメソッドは、各テストメソッドが呼び出される前に毎回必ず呼び出されます。フィクスチャのセットアップをする必要がある場合などに使ってください。

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

「after」ネームスペースで修飾されたメソッドは、各テストメソッドが呼び出された後に毎回必ず呼び出されます。フィクスチャの終了処理をする必要がある場合などに使ってください。

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

「beforeClass」ネームスペースで修飾されたメソッドは、テストクラス内の全てのテストが実行される前に1度だけ呼び出されます。フィクスチャのセットアップをする必要がある場合などに使ってください。

afterClass

「afterClass」ネームスペースで修飾されたメソッドは、テストクラス内の全てのテストが実行された後に1度だけ呼び出されます。フィクスチャの終了処理をする必要がある場合などに使ってください。

test_expected

正しく例外がスローされているかどうかテストしたい場合は、例外がスローされることを期待するテストメソッドと同じ名前で、static、constなプロパティを作り、test_expectedネームスペースで修飾して、期待される例外クラスを指定してください。

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

use namespace test;
use namespace test_expected;

public class SampleTest
{
    // ArgumentErrorがスローされることを期待
    test_expected static const error:Class = ArgumentError;
    test function error():void
    {
        var s:Sample = new Sample();
        s.e(null);
    }
}

テストスイート

複数のテストをひとまとめにするために、テストスイートを作ることが出来ます。次のようなクラスを作り、SuiteClasses?配列の中に、テストクラスを列挙してください。

クラス名は何でも構いませんが、AllTests?にするのが一般的です。

import org.libspark.as3unit.runners.Suite;

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

テストスイートを入れ子にする(SuiteClasses?の中で更にテストスイートを指定する)ことも勿論可能です。

テストの実行

テストを実行するには、AS3UnitCoreクラスを使用するのが簡単です。mainメソッドを、テスト対象のクラスを引数として呼び出すと、結果がtraceされます。

import org.libspark.as3unit.runner.AS3UnitCore;

...

AS3UnitCore.main(AllTests);

非同期処理のテスト

AS3Unit for Asyncでは、非同期処理のテストを行うことが出来ます。

非同期処理のテスト行うには、org.libspark.as3unit.assert.async関数を使います。async関数は、Functionと制限時間を引数に取り、チェックポイント関数を返します。

このチェックポイント関数が、制限時間内に呼び出されるとテストがパスします。チェックポイント関数が呼び出される際、引数として渡したFunctionを呼び出すので、そこで更にアサーションを行うことも可能です。

次の例は、Timerクラスのテストです。タイマーが終了(TimerEvent?.TIMER_COMPLETE)した時に、Timerのコンストラクタで指定した回数分、TimerEvent?.TIMERが発行されているかをテストします。

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();
    }
}

注目すべきは、

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

の部分です。イベントハンドラを、チェックポイント関数でラップしています。これにより、このTIMER_COMPLETEハンドラが呼ばれることで、はじめてテストがパスするようになります。

「, 1000」と書いてある部分が制限時間(ミリ秒)で、TIMER_COMPLETEハンドラが呼ばれずに1000ミリ秒が経過すると、TimeoutError?でテストが失敗します。

イベントハンドラの中では、assertEqualsを使い、TIMERハンドラが呼び出された回数(count変数)が、期待する3であるかどうかをテストしています。

AS3Unit自身のテストケースのひとつである、AsyncTestも参考にどうぞ。