対象読者
Kotlinで開発しているAndroidエンジニア
はじめに
みなさん、ユニットテストは書いてますか?
コードカバレッジはどうでしょうか?
コードカバレッジとは?
ソースコードのテストされた割合です。
測定手法がいくつかありますが、今回は2つだけご紹介します。
命令網羅(C0)
ソースコードの 各文 が実行されているかどうか。
fun hoge(x: Int) {
println("hoge")
if (x > 0) {
println("fuga")
}
}
hoge(x = 1)
だけで C0:100%
分岐網羅(C1)
ソースコードの 各条件 が実行されているかどうか。
fun hoge(x: Int) {
println("hoge")
if (x > 0) {
println("fuga")
}
}
hoge(x = 1)
と hoge(x = 0)
で C1:100%
コードカバレッジ、何か嬉しいことがあるの?
ユニットテストが充分か?の判断基準の一つとして使えます。
例として、既存コードのリファクタリングを考えてみます。
既存コード
fun hoge(x: Int): String {
if (x >= 3) return "many"
if (x == 2) return "two"
if (x == 1) return "one"
if (x == 0) return "zero"
return "other"
}
ユニットテストを書く
@Test
fun hogeTest() {
assert(hoge(3) == "many")
assert(hoge(2) == "two")
assert(hoge(1) == "one")
assert(hoge(0) == "zero")
}
でも、このユニットテストで充分なのだろうか・・・?
そこでコードカバレッジ!
コードカバレッジを計測する方法
- Android Studio
- JaCoCo 今回はこちらをご紹介
- Other...?
JaCoCoの準備
デフォルト設定だと、
Kotlinが計測対象になりません
arturdm/jacoco-android-gradle-plugin Issue 37 の JaCoCoの設定 を参考にすればOK
※上記の設定は build variants も考慮されていてステキ
カバレッジ結果をみてみる
$ gradlew jacocoDebugReport
実行後に、
app/build/reports/jacoco/jacocoDebugReport/html/index.html
を開きましょう。
アプリ全体のレポート
クラスごとのレポート
クラス内の各関数ごとのレポート
ソースコードレベルのレポート
緑:分岐網羅 OK
黄:分岐網羅 NG(片方の分岐しか実行されてない、など)
赤:一度も実行されていない
テストコードを足す
カバレッジレポートを見たところ、ユニットテストに不足があることがわかりました。
テストコードを追加しましょう。
@Test
fun hogeTest() {
assert(hoge(3) == "many")
assert(hoge(2) == "two")
assert(hoge(1) == "one")
assert(hoge(0) == "zero")
assert(hoge(-1) == "other") // ★追加テストコード
}
無事、カバレッジ100%
これで、ある程度信頼できるユニットテストができました。
なので、リファクタリングも怖くありません。
Kotlinっぽくしてみる
fun hoge(x: Int): String =
when {
x >= 3 -> "many"
x == 2 -> "two"
x == 1 -> "one"
x == 0 -> "zero"
else -> "other"
}
分岐網羅100%&ユニットテストも通っているので、大丈夫そうです。
補足
- カバレッジ100%だからユニットテスト完璧、ではない
- でも、判断基準の一つとして使えます
- カバレッジ100%必達では無い
- 例えばユニットテスト書きづらいところは、手動で確認しても良いと思います