Spekではじめるユニットテスト
Ippei Nawate @R.kt #1 2017/10/04
自己紹介
- Ippei Nawate
- Software Developer
- Android(Java, Kotlin)
- Ruby
- 筑波大学(~ 2016/03)
- リクルートライフスタイル(2016/04~)
- Hotpepper Beauty for Android
http://spekframework.org/
Spek?
- Kotlin製のSpecification Framework
- https://github.com/JetBrains/spek
- v1.1.5
- そろそろv2.0が出そう
- https://github.com/JetBrains/spek/milestone/3
- JetBrains非公式(!)
- JUnit Platform(JUnit 5)上で動作する
- RSpecライクなDSL(describe, on, it ...)を使ってテストケースを記述
Spek?
JUnit5
JUnit Platform
TestEngine(Interface)
JUnit Vintage JUnit Jupiter Spek
Next Generation Of JUnit
JUnit5
@RunWith(JUnitPlatform::class)
TestEngine(Interface)
JUnit Vintage JUnit Jupiter Spek
Next Generation Of JUnit
JUnit4
JUnit 5?
- Next generation of JUnit
- JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
- JUnit Platform
- テスト実行基盤を提供
- TestEngineという仕組みを通じてテストケースの収集と実行を行う
- JUnit Jupiter
- JUnit 5での新しいテストプログラミングモデル (+それを実行するための TestEngine)を提
供
- JUnit Vintage
- JUnit3, 4のテストコードをJUnit Platform上で実行するための TestEngineを提供
JUnit 5?
- JUnit3, 4上でTestEngineを動かすことも出来る
- テストクラスに@RunWith(JUnitPlatform::class)を指定する
- JUnitPlatform::class == TestRunner
- Androidではこれを使ってSpekを動かす必要がある(*1)
*1: https://github.com/aurae/android-junit5 を使ってJupiter形式のテストを実行することは可
能(ただしSpekと組み合わせることはできない模様 )
テストの書き方
1. テストクラスにSpekを継承させる
2. Spekのコンストラクタに渡すクロー
ジャ内にテストを記述
3. DSLを利用してテストを記述
a. describe, given, contextを使ってテストを
グルーピングしていく
b. it内に実際の検証処理を記述
c. 各テストの前/後処理は
before/afterEachTestに記述
i. JUnitで言うsetup/teardown
基本
Q&A - JUnit 4と比較して
Q. TestRule相当のものはあるの?
A. TestLifecycleListenerという仕組みがある。ただし@ClassRuleのような使い方は
できない。
Q. 独自ベースクラス作れる?
A. 作れるけど少し特殊(後述)
Q. カバレッジ測れる?
A. これまで通りJacocoで測れます
独自ベースクラスの作り
- Spekのテストクラスは以下2つから構成される
- Spek:テストのベースクラス
- Spec:テストのDSLを定義するインターフェース
- それぞれを拡張する必要がある
Spec.() -> Unit型のクロージャ
独自ベースクラス
ベースクラス
パラメタライズドテスト
● for文で気軽に書ける
● 関数(it)呼び出し == 1テストケース
なので入力毎にテストケースが独立
● data-driven-extensionを使う手もある
○ https://github.com/JetBrains/spek/tree/m
aster/spek-data-driven-extension
Spekのハマりどころ
1. 変数スコープ
Spekのハマりどころ - 1. 変数のスコープ
右のテストは失敗します
Spekのハマりどころ - 1. 変数のスコープ
A. テストケースの収集と実行のフェーズが分かれているから
① 収集
② 実行
2. テストの探索
Spekのハマりどころ - 2. テストの探索
このテストはパスします
Spekのハマりどころ - 1. 変数のスコープ
- 探索フェーズで例外が起きると無視される
- 警告: TestEngine with ID 'spek' failed to discover tests
- ↑↑が標準エラーに吐かれるだけ
- SpekじゃなくててJUnit 5の仕様(不具合?)っぽい
- https://github.com/junit-team/junit5/issues/242
- https://github.com/junit-team/junit5/issues/750
- 5.1で修正予定らしい
A. 「テストケースが見つかりませんでした」扱いになるから
まとめ
- pros
- JUnit 4でできてたことは大体できる
- 条件部と検証部が分離されて読みやすい
- ネストさせることで、共通の条件部を自然に書ける
- パラメタライズドテストやりやすい
- cons
- 拡張するのにKotlinの深めの知識が求められる
- 変数のスコープでハマりがち
- JUnit 5自体も枯れきってない感

Spekではじめるユニットテスト