unassert - encourage reliable programming by writing assertions in productionTakuto Wada
unassert - Encourage Design by Contract (DbC) by writing assertions in production code, and compiling them away from release.
Takuto Wada
2015/11/07 @nodefest Tokkyo 2015
This document summarizes Takuto Wada's presentation on reviewing RESTful web apps. It discusses best practices for designing RESTful resources and representations, including using nouns instead of verbs in URLs, making URLs reflect the meaning of resources, and ensuring resources are connected through hypermedia links and forms. It also covers appropriate use of HTTP methods, status codes, and content negotiation to build RESTful APIs in accordance with best practices.
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] がつかえる
● テスト名をテストクラスのコンストラクタに渡す