torutkのブログ

ソフトウェア・エンジニアのブログ

FEST-SwingでSwingクラスの自動ユニットテスト(最初の一歩編)

id:torutk:20110130(インストール編)の続きです。

FEST-Swingのサイトには、最初の一歩(Getting Started)となる解説が掲載されています(以下URL)。

このサンプルコードはTestNG用なので、ちょっとだけ(アノテーション部分)JUnitでは変更する必要があります。

import org.fest.swing.fixture.FrameFixture;

public class MyFrameTest {
    private FrameFixture window;

クラス定義はJUnit 4.x と同様です。フィールドにFEST-Swing特有のFrameFixtureを定義します。

import org.junit.BeforeClass;
import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
   :
   @BeforeClass
    public static void setUpClass() throws Exception {
        FailOnThreadViolationRepaintManager.install();
    }

テストクラスで1回だけ初期化するメソッド(JUnitの@BeforeClassアノテーションしたメソッド)の中で、テスト対象コードがSwingスレッド規範に違反しているかを検出するための機能を設定します。実装は、Swingのリペイントマネージャを拡張してSwingのデフォルトのリペイントマネージャと入れ替えています。

import org.junit.BeforeClass;
import org.fest.swing.edt.GuiQuery;
import org.fest.swing.edt.GuiActionRunner;
import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
    :
    @Before
    public void setUp() {
        MyFrame frame = GuiActionRunner.execute(new GuiQuery<MyFrame>() {
            @Override
            protected MyFrame executeInEDT() {
                return new MyFrame();
            }
        });
        window = new FrameFixture(frame);
        window.show();
    }

テストケース毎に初期化するメソッド(JUnitの@Beforeアノテーションしたメソッド)の中で、まず、テスト対象のJFrameサブクラスのインスタンスをイベントディスパッチスレッドで生成します。コードがちょっとぎょっとする内容ですが、やっていることはnew MyFrame() です。
次に、FrameFixtureクラスのインスタンスを生成し、表示します。なお、FrameFixtureは、java.awt.Robotを使用して自動テストを実現しています。

import org.junit.After;
    :
    @After
    public void tearDown() {
        window.cleanUp();
    }

テストケース毎に後始末処理するメソッド(JUnitの@Afterアノテーションしたメソッド)の中で、FrameFixtureクラスのcleanUp()を呼んで、テストで使用したウィンドウのリソースを後始末しています。

import org.junit.Test;
    :
    @Test
    public void sholdCopyTextInLabelWhenClickingButton() {
        window.textBox("textToCopy").enterText("Some random text");
        window.button("copyButton").click();
        window.label("copiedText").requireText("Some random text");
    }

いよいよ本題のテスト部分です。
FrameFixtureインスタンスに、テストで行いたいGUI上の操作と確認したい状態を指示するメソッドを呼び出します。画面上には実際にテスト対象のGUIが表示され、この例では、テキストフィールドに文字"Some random text"が自動で入力され、ボタンが押され、ラベルに入力した文字が表示され、と自動で処理が進みます。

ここで注意点、SwingのGUIコンポーネントでFrameFixtureから制御・状態取得したいものには、setNameメソッドで名前を指定しておく必要があります。この例では、ユーザーが文字列を入れるJTextFieldに、setName("textToCopy")と名前を設定し、JButtonにはsetName("copyButton")、JLabelにはsetName("copiedText")とそれぞれ名前を設定しています。

NetBeansでは、プロパティのname項目に記述してもOKです。

実行は、JUnitのテスト実行と同じです。