spock's world
DESCRIPTION
JJUG CCC 2012 Fall でのスライドです。TRANSCRIPT
Spock’s World
JJUG CCC 2012 Fall R3-1株式会社デライトテクノロジーズ 綿引琢磨
本スライドの対象
普段 Eclipse を使っている Java デベロッパー全般
JUnit を使っているが、もうちょっとスマートにテストを書きたいと思っている人
テストのないプロジェクトで困っているマネージャー・リーダー
自己紹介
綿引琢磨(わたびきたくま)
twitter : bikisuke
株式会社デライトテクノロジーズ 代表取締役
日本 Grails / Groovy ユーザーグループ運営委員
Java / Groovy エンジニア
アジェンダ
JUnit から Spock へ
Spock の基礎
Spock についてのよくある誤解
Spock の機能拡張
JUnit から Spock へ
JUnit を積極的に使いたい理由
テストの自動化ができる
Eclipse に標準装備
プロダクトコードと同じ Java で書ける
書籍や Web など情報が豊富
etc.
JUnit の物足りないところ
モックの仕組みがない(モックフレームワークが別途必要)
パラメタライズドテストが残念
パラメータの配列を・・・
どのパラメータがエラーかわからない(ひと工夫いる)
そこで Spock ですよclass HelloSpock extends spock.lang.Specification { def "length of Spock's and his friends' names"() { expect: name.size() == length
where: name | length "Spock" | 5 "Kirk" | 4 "Scotty" | 6 }}
Spock とはGroovy 上に構築されたテストフレームワーク
Groovy の機能を活用し、DSL によるシンプルで可読性の高いテストコードを実現
強力な Assert 機能でエラー箇所の特定が容易
JUnit 互換のため IDE からも実行可能
開発者向けの仕様テストとして、BDD も実践可能
JUnit との比較JUnit Spock
記述言語 Java Groovy
テストの自動化 ◎ ◎Eclipse 標準装備 ◎ △技術情報 ◎ △
モックの仕組み △ ◎パラメタライズド △ ◎仕様テスト × ◎
Spock の基礎
Eclipse での環境整備Eclipse-Groovy プラグインのインストール
http://groovy.codehaus.org/Eclipse+Plugin
Eclipse の設定
「use monospace font for junit」 にチェック
Groovy プロジェクトへの変換
[Configure] > [Convert to Groovy Project]
ライブラリの追加
テストクラスの構造@RunWith(Sputnik.class)
Specification
HelloSpec
フィクスチャメソッド()
フィーチャメソッド()
ヘルパーメソッド()
org.junit.runner.Runner を継承
処理の流れ
テストコード
バイトコード
AST変換字句解析構文解析
コード生成
テスト実行
処理の流れ
テストコード
バイトコード
AST変換字句解析構文解析
コード生成
テスト実行
• DSL の解析• モック/例外実装の追加• メタ情報の追加• モデルの構築
フィクスチャメソッドsetup()
各フィーチャメソッドの実行前に呼ばれる。
cleanup()
各フィーチャメソッドの実行後に呼ばれる。
setupSpec()
最初のフィーチャメソッドの実行前に呼ばれる。
cleanupSpec()
最後のフィーチャメソッドの実行後に呼ばれる。
フィーチャメソッド
テストメソッドを指す
JUnit の場合、@Test を付けるメソッドに当る
メソッド名は文字列で表現するのが習慣
最低1つのブロックを含んでいる必要がある
ブロックブロック名 フェーズ 概要
setup / given Setupフィーチャの設定作業(前提条件)を記述する。先頭に記述する必要がある。
when Stimulusテスト対象の振る舞いを記述する。then
ブロックとセットで使用する必要がある。
then Responsewhen ブロックに対する条件、例外条件、インタラクションを記述する。
expect Stimulus /Response
条件を記述する。then ブロックよりも記述制限がある。
cleanup Cleanupフィーチャ内でのリソースの解放作業を記述する。
where -データドリブンテストの場合に記述する。フィーチャの最後に記述する必要がある。
データドリブンテスト
Spock を使用するメリットの一つ
パラメタライズドテストをスマートに記述
データはテーブル書式またはコレクションで表現
Assert 機能により、エラー箇所が明確にわかる
例外に関するテスト
以下の4メソッドで検証可能
<T extends Throwable> T thrown()
<T extends Throwable> T thrown(Class<T> type)
void notThrown (<T extends Throwable> type)
void noExceptionThrown()
テストダブル (Mock/Stub/Spy)
インタラクションの代役を生成
Java / Groovy オブジェクト用の API
任意の代役を表現するワイルドカードも使える
Stub の振る舞い
http://yamkazu.hatenablog.com/entry/2012/10/20/222558
テストダブルの詳細 http://xunitpatterns.com/Test%20Double%20Patterns.html
Spock についてのよくある誤解
テストを Spock (Groovy) で書くと、リファクタリングできないんじゃないの?
普通にできます。
Groovy の PowerAssert でいいんじゃないの?
PowerAssert と同じではありません。
JUnit の Rule アノテーションを活用してるから、Spock
に移行できません。
Rule アノテーションもそのまま使えます。
Spock の機能拡張
2つの拡張方法
グローバル拡張
実行コンテキストの構築時に対象のテストに対して適用される
アノテーションドリブン拡張
クラスやメソッド、フィールド単位でテスト実行時に適用される
拡張処理の流れ
テストコード
バイトコード
AST変換字句解析構文解析
コード生成
テスト実行
拡張処理の流れ
テストコード
バイトコード
AST変換字句解析構文解析
コード生成
テスト実行
•実行コンテキストの構築•グローバル拡張の適用
拡張処理の流れ
テストコード
バイトコード
AST変換字句解析構文解析
コード生成
テスト実行
• アノテーション ドリブン拡張の適用
•実行コンテキストの構築•グローバル拡張の適用
グローバル拡張JUnit アダプタ
JUnitFixtureMethodsExtension
JUnit Rules 適用
RuleExtension / ClassRuleExtension
テスト実行可否
IncludeExculdeExtension
テスト最適化
OptimizeRunOrderExtension
アノテーションドリブン拡張
@AutoCleanup
@FailsWith
@Ignore / @IgnoreIf / @IgnoreRest
@Stepwise
@Timeout
@Unroll
@Use
Spock 関連情報
ソースリポジトリ
https://github.com/spockframework/spock
ドキュメント
http://docs.spockframework.org/en/latest/
Wiki (上記ドキュメントに移行予定)
http://code.google.com/p/spock/w/list
日本での情報G* ワークショップ
隔月程度のペースで都内を中心に開催
G* Magazine
年に数回発刊している日本語で読める唯一の
Groovy 関連電子雑誌
PDF : http://grails.jp/g_mag_jp/index.html
EPUB : http://beta.mybetabook.com/u/jggug/
ご清聴ありがとうございました
Spock’s World
JJUG CCC 2012 Fall R3-1株式会社デライトテクノロジーズ 綿引琢磨