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
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 Do This
● オブジェクト指向言語を使うとき、 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
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());
}
}
}
9. Further Reading
● xUnit のいくつか(たとえば VbUnit や NUnit)で
は、 Testcase Class は “test fixture” と呼ばれる
● xUTP の文脈で言うところの Test Fixture と混同して
はならない
● Fit フレームワークも fixture という言葉をつかう
● Fit の fixture は Fit table の Adapter で、 Data-
Driven Test の Interpreter として作用する
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 Do This
● 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 とか)
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 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 のインスタンスを使いまわす
21. Implementation Notes
● Testcase Object が標準的な interface を実装し
ているので、 Test Runner はテストの中身を気に
せずに実行できる
● これが Command [GoF] の威力!
● Test
● Test Method 毎にクラスを分けることもできるがオスス
メしない
– Test Utility Method の共有を妨げる
● どのテストを実行するかを指定する仕組みが必要
– Pluggable Behaviour [SBPP] がつかえる
● テスト名をテストクラスのコンストラクタに渡す