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] がつかえる
             ●   テスト名をテストクラスのコンストラクタに渡す
ご清聴
 ありがとう
ございました

xUTP Chapter19 (2). Testcase Class

  • 1.
  • 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
  • 3.
  • 4.
    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
  • 5.
    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) がまとめて実行する
  • 6.
    Why We DoThis ● オブジェクト指向言語を使うとき、 Test Method を グローバル関数や手続きにするのではなく、 クラス に置きたい ● Test Method を Testcase Class のインスタンス メソッドにしておくことで、 Test Method 毎に Testcase Class をインスタンス化し、 Testcase Object を作成することができる ● この方法であれば、実行時に Test Method に手を入 れる (manipulate) ことができる ● もちろん Test Method 毎にクラスを作る手もある が、オーバーヘッドはあるし名前空間は荒れるしテ スト間の共通化、再利用は難しくなるしで良いこと がない
  • 7.
    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) にしたりできる
  • 8.
    Example: Testcase Class publicclass 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()); } } }
  • 9.
    Further Reading ● xUnit のいくつか(たとえば VbUnit や NUnit)で は、 Testcase Class は “test fixture” と呼ばれる ● xUTP の文脈で言うところの Test Fixture と混同して はならない ● Fit フレームワークも fixture という言葉をつかう ● Fit の fixture は Fit table の Adapter で、 Data- Driven Test の Interpreter として作用する
  • 10.
  • 11.
    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
  • 12.
    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) …などを使う
  • 13.
    How It Works(2) ● 走らせる Composite は以下のどれでも良い ● 単一の Testcase Object ● Test Suite Object ● Composite Test Suite (Suite of Suite) ● どれでも同じように走らせられるのは同じ interface を実装しているから ● Test Runner は実行に際して単一のテストを実行して いるのか複数のテストを実行しているのかを意識しなく て良い ● Test Runner はテスト実行、アサーション失敗、エ ラーや例外の数などをトラッキングしてレポートする
  • 14.
    Why We DoThis ● test automator によってテスト実行の流儀が違う のは望ましくない。誰でも同じように実行できるのが 望ましい ● Test Runner を標準にすることで、他の人の書いた テストコードでも楽に実行できる ● 別の方法で同じテストを実行する手段も同時に提供で きる(★?)
  • 15.
    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 的に解決する
  • 16.
    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 とか)
  • 17.
  • 18.
    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
  • 19.
    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 群をつくる
  • 20.
    Why We DoThis ● テストを手続きでなく first-class object として扱う ことで、いろいろな可能性が開ける ● オブジェクトであれば、 Test Runner や Test Automation Framework から操作(や介入)しやすい – コレクションとして持つこともでき (Test Suite Object) ,それ らをイテレートし、実行し… ● xUnit ファミリー (のほとんど) は Test Method 毎 に独立した Testcase Object のインスタンスを作 り、 Independent Test (p42) を実現する ● もちろん、例外はある (TestNG や NUnit) – Testcase Object のインスタンスを使いまわす
  • 21.
    Implementation Notes ● Testcase Object が標準的な interface を実装し ているので、 Test Runner はテストの中身を気に せずに実行できる ● これが Command [GoF] の威力! ● Test ● Test Method 毎にクラスを分けることもできるがオスス メしない – Test Utility Method の共有を妨げる ● どのテストを実行するかを指定する仕組みが必要 – Pluggable Behaviour [SBPP] がつかえる ● テスト名をテストクラスのコンストラクタに渡す
  • 22.