Upload
takuto-wada
View
1.980
Download
4
Embed Size (px)
DESCRIPTION
handout for xUnit Test Patterns Reading Group Japan
Citation preview
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) にしたりできる
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()); } }
}
Example: Testcase Class
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] がつかえる
● テスト名をテストクラスのコンストラクタに渡す
ご清聴ありがとうございました