Skip to main content
Chapter 19.
xUnit Basic
Patterns(2)
●   Test Definition
    ●   Test Method
        –   Four-Phase Test
    ●   Assertion Method
        –   Assertion Message
    ●   Testcase Class
●   Test Execution
    ●   Test Runner
    ●   Testcase Object
    ●   Test Suite Object
    ●   Test Discovery
    ●   Test Enumeration
    ●   Test Selection
Testcase Class
●   Test Definition
    ●   Test Method
        –   Four-Phase Test
    ●   Assertion Method
        –   Assertion Message
    ●   Testcase Class
●   Test Execution
    ●   Test Runner
    ●   Testcase Object
    ●   Test Suite Object
    ●   Test Discovery
    ●   Test Enumeration
    ●   Test Selection
Testcase Class
●   テストコードをどこに書く?
    ●   関連する Test Method を単一の Testcase Class に
        配置する
    ●   Testcase Class は複数の Test Method の置き場所と
        なり、(実行時にそれらメソッドは) Testcase Object に
        なる
●   How It Works
    ●   Testcase Class は実行時に Test Suite Factory
        (p399) として働き、 Test Method 毎に Testcase
        Object を作成する
    ●   Testcase Class は作成した Testcase Object を Test
        Suite Object (p387) に渡し、 Test Runner (p377)
        がまとめて実行する
Why We Do This
●   オブジェクト指向言語を使うとき、 Test Method を
    グローバル関数や手続きにするのではなく、 クラス
    に置きたい
●   Test Method を Testcase Class のインスタンス
    メソッドにしておくことで、 Test Method 毎に
    Testcase Class をインスタンス化し、 Testcase
    Object を作成することができる
    ●   この方法であれば、実行時に Test Method に手を入
        れる (manipulate) ことができる
●   もちろん Test Method 毎にクラスを作る手もある
    が、オーバーヘッドはあるし名前空間は荒れるしテ
    スト間の共通化、再利用は難しくなるしで良いこと
    がない
Implementation Notes
●   Testcase Class の魔法は実行時に現れる
    ●   詳しくは Testcase Object と Test Runner 参照
    ●   テストロジックを Test Method に書いてあとは Test
        Runner の魔法に任せれば良い
●   Test Code Duplication (p213) は Extract
    Method して Test Utility Method にする
    ●   抽出したメソッドを…
        –   (Abstract) Testcase Superclass (p638) に引き上げたり
        –   Test Helper class (p643) にしたり
        –   Test Helper Mixin (p638) にしたりできる
Example: Testcase Class
public class TestScheduleFlight extends TestCase {

    public void testUnscheduled_shouldEndUpInScheduled() throws Exception {
      Flight flight = FlightTestHelper.getAnonymousFlightInUnscheduledState();
      flight.schedule();
      assertTrue("isScheduled()", flight.isScheduled());
    }
                     
    public void testScheduledState_shouldThrowInvalidRequestEx()
         throws Exception {
      Flight flight = FlightTestHelper.getAnonymousFlightInScheduledState();
      try {
         flight.schedule();
         fail("not allowed in scheduled state");
      } catch (InvalidRequestException e) {
         assertEquals("InvalidRequestException.getRequest()",
                        "schedule", e.getRequest());
         assertTrue("isScheduled()", flight.isScheduled());
      }
    }

}
Further Reading
●   xUnit のいくつか(たとえば VbUnit や NUnit)で
    は、 Testcase Class は “test fixture” と呼ばれる
    ●   xUTP の文脈で言うところの Test Fixture と混同して
        はならない
●   Fit フレームワークも fixture という言葉をつかう
    ●   Fit の fixture は Fit table の Adapter で、 Data-
        Driven Test の Interpreter として作用する
Test Runner
●   Test Definition
    ●   Test Method
        –   Four-Phase Test
    ●   Assertion Method
        –   Assertion Message
    ●   Testcase Class
●   Test Execution
    ●   Test Runner
    ●   Testcase Object
    ●   Test Suite Object
    ●   Test Discovery
    ●   Test Enumeration
    ●   Test Selection
Test Runner
●   テストをどうやって実行する?
    ●   Test Suite Object をインスタンス化し suite 内の
        Testcase Object 全てを実行するようなアプリ (Test
        Runner) を使う
●   How It Works
    ●   xUnit ファミリーには CUI や GUI からテストを実行して
        結果をレポートさせる機能がある
    ●   Test Runner はテストの Composite[GoF] を作るため
        に…
        –   Test Enumeration (p399)
        –   Test Discovery (p393)
        –   Test Selection (p403) …などを使う
How It Works (2)
●   走らせる Composite は以下のどれでも良い
    ●   単一の Testcase Object
    ●   Test Suite Object
    ●   Composite Test Suite (Suite of Suite)
●   どれでも同じように走らせられるのは同じ
    interface を実装しているから
    ●   Test Runner は実行に際して単一のテストを実行して
        いるのか複数のテストを実行しているのかを意識しなく
        て良い
●   Test Runner はテスト実行、アサーション失敗、エ
    ラーや例外の数などをトラッキングしてレポートする
Why We Do This
●   test automator によってテスト実行の流儀が違う
    のは望ましくない。誰でも同じように実行できるのが
    望ましい
●   Test Runner を標準にすることで、他の人の書いた
    テストコードでも楽に実行できる
    ●   別の方法で同じテストを実行する手段も同時に提供で
        きる(★?)
Implementation Notes
●   代表的な Test Runner は
    ●   IDE に統合された GUI から使う Test Runner
    ●   コマンドラインから走らせる Test Runner
●   Standard Test Interface があるから Test
    Runner はどれでも実行できる
    ●   静的型付け言語の場合は Testcase Object や Test
        Suite Object が実装すべき interface を提供している
        –   C# や新しめの Java では attribute や annotation で素のク
            ラスに test interface を織り込めるものがある
    ●   動的型付け言語の場合は明示的な test interface は
        無いが、 duck-typing 的に解決する
Implementation Notes (2)
●   代表的な test interface は…
    ●   テストの数を答えるメソッド
    ●   テストを実行するメソッド
    ●   テストフレームワークが Test Enumeration をサポートする
        場合には、 Testcase Class や suite class (★特定の仕組
        みを継承しない AllTests などか★) は Test Suite Factory
        メソッド (たいがいは “suite” というメソッド) も実装しないと
        いけない
●   Test Runner のバリエーション
    ●   GUI
    ●   コマンドライン
    ●   File System Test Runner (指定ディレクトリ以下を探す)
    ●   Test Tree Explorer (Eclipse の Test Tree とか)
Testcase Object
●   Test Definition
    ●   Test Method
        –   Four-Phase Test
    ●   Assertion Method
        –   Assertion Message
    ●   Testcase Class
●   Test Execution
    ●   Test Runner
    ●   Testcase Object
    ●   Test Suite Object
    ●   Test Discovery
    ●   Test Enumeration
    ●   Test Selection
Testcase Object
●   テストをどうやって実行する?
    ●   Command[GoF] オブジェクトを各テスト (Test
        Method) 毎に作成し、 run メソッドを呼び出す
    ●   この機能があるので、 GUI の Test Runner は Tree を
        クリックしてテストを一つ選択して実行とかできる
●   How It Works
    ●   各テスト毎に Command オブジェクトをつくる
        –   Testcase Class を Test Suite Factory として使い、
            Testcase Object を保持する Test Suite Object を作る
        –   Test Discovery または Test Enumeration を使って
            Testcase Object 群をつくる
Why We Do This
●   テストを手続きでなく first-class object として扱う
    ことで、いろいろな可能性が開ける
    ●   オブジェクトであれば、 Test Runner や Test
        Automation Framework から操作(や介入)しやすい
        –   コレクションとして持つこともでき (Test Suite Object) ,それ
            らをイテレートし、実行し…
●   xUnit ファミリー (のほとんど) は Test Method 毎
    に独立した Testcase Object のインスタンスを作
    り、 Independent Test (p42) を実現する
    ●   もちろん、例外はある (TestNG や NUnit)
        –   Testcase Object のインスタンスを使いまわす
Implementation Notes
●   Testcase Object が標準的な interface を実装し
    ているので、 Test Runner はテストの中身を気に
    せずに実行できる
    ●   これが Command [GoF] の威力!
●   Test
    ●   Test Method 毎にクラスを分けることもできるがオスス
        メしない
        –   Test Utility Method の共有を妨げる
    ●   どのテストを実行するかを指定する仕組みが必要
        –   Pluggable Behaviour [SBPP] がつかえる
             ●   テスト名をテストクラスのコンストラクタに渡す
ご清聴
 ありがとう
ございました