More than 1 year has passed since last update.

この記事は、Android Advent Calendar 2015 19日目の記事です。
Vim Advent Calendarの17日目の記事は期限の3分前に何とかpostできましたが、こちらは初めてのGradleプラグイン開発に手こずってしまい、27時間ほど遅刻してのpostとなってしまいました:sweat_drops:すみません:bow:

皆さんは、Androidアプリケーション開発において、テストカバレッジ計測をどのように実施していますか?
Android Gradle Plugin 0.10.0からJaCoCoがサポートされ手軽にカバレッジ計測が実施できるようになったため、それを利用されている方も多いと思います。(私もそれで計測しています)

カバレッジ計測結果の判定

手軽にカバレッジ計測できるようになった事は良いのですが、その計測結果の判定を自動的に実施できない点を、これまで不満に思っていました。
「計測結果の判定を自動的に実施する」の補足ですが、カバレッジが〜%未満ならビルドに失敗させる、のような機能の事を指しています。JavaScriptでいうとkarma-coverageのcheck機能みたいなやつです。

Android Gradle Plugin からカバレッジ計測をする際に↑に近いことをする方法を見つけることができなかったので、Gradleプラグインという形で実装してみました。

gradle-android-coverage-check

gradle-android-coverage-check

gradle-android-coverage-checkはAndroid Gradle Plugin(JaCoCo)で計測したカバレッジをチェックするためのプラグインです。

導入後にandroidCoverageCheckタスクを実行すると以下のようなログが表示され、カバレッジが閾値を満たさない場合はビルドを失敗させることができます(後のOptionの項目で触れますが、ビルドは失敗させず、ログのみ表示することも可能です)。
スクリーンショット 2015-12-21 0.50.27.png

(ログの見栄えはkarma-coverageを参考にしています、というかまんまですね)

INSTRUCTIONとBRANCH以外の値(COMPLEXITYやMETHODやLINEなど)も今後チェックできるようにする予定です。

Install

依存関連

build.gradle
buildscript {
    repositories {
        maven {
            url 'https://github.com/shikato/gradle-android-coverage-check/raw/master/repository'
        }
    }
    dependencies {
        classpath 'org.shikato.gradle.android.coverage.check:android-coverage-check:0.0.2'
    }
}

AndroidCoverageCheckプラグインの適用

build.gradle
apply plugin: 'android-coverage-check'

せっかくなのでここに登録したかったのですが、間に合いませんでした、、(後に登録できればと思ってます)

Task

カバレッジ計測と合わせてチェック

./gradlew createDebugCoverageReport androidCoverageCheck  

チェックのみ実行(既にカバレッジレポートファイルが存在している必要があります)

./gradlew androidCoverageCheck  

Option

build.gradle
// チェック対象外ファイル
// Default: []
String[] excludeFiles = ["**/*Activity.java",
                         "**/*Fragment.java",
                         "package/name/**/Shikato2.java"];

// Android Gradle Pluginが出力するカバレッジレポートの場所
// Build Variantsを使っている場合などで複数レポートが存在する場合はそれぞれ別々にチェックされます
// Default: ["**/coverage/**/report.xml"]
String[] reportXmlPath = ["hoge/fuga/**/report.xml"];

androidCoverageCheck {
    // 閾値未満の時にビルド失敗させるかどうか
    // Default: true
    isBuildFailure false

    // INSTRUCTIONの閾値
    // Default: 20
    instruction 70

    // BRANCHの閾値
    // Default: 20
    branch 50

    // それぞれ(除外ファイル、カバレッジレポートのpath)をセット
    excludes excludeFiles
    reportXml reportXmlPath
}

今後、指定のファイルのみ特定の閾値を設定する、みたいなオプションを追加しようと思っています。

CircleCIとの連携

CircleCIでも動作するか試してみました。
スクリーンショット 2015-12-21 1.17.50.png
ログの表示がちょっとおかしいですが、閾値を満たさなかった際にビルドを失敗させることができました。

AndroidCoverageCheckプラグインをCircleCIで試したサンプルプロジェクトは、GitHubにもupしてあります。
circleci-sample-for-android

さいごに

カバレッジはソフトウェアの品質が高いことを必ずしも保証するものではないですが、テストコートの品質を定量的に測る上では、やはり手軽かつ便利なので、Androidアプリケーション開発においても高いカバレッジを維持していきたいと思っています。
(リポジトリを見られた方の中には、AndroidCoverageCheckプラグイン自身のテストコードが皆無なのでは。カバレッジ0%なのでは。ビルド失敗させるべきなのでは。と思いの方もおられるかもですが、すみません。現時点では間に合いませんでした。今後書いていきます。としか言い訳のしようがありません:bow:

それと以下記事にもあるように、自動的に強制できるものは出来る限り、そのようにすべきとも思います(もちろんメンバーの同意を得た上でですが)。

コーディング規約に従うことで、プロジェクトの全体としての進行を円滑にし、開発速度を一定に保ちやすくします。
ただし重要なのは、プロジェクトに参加する全員が同じ規約に従わなくてはならないということです。
―他の開発者が皆4タブのインデントを使用しているのに、1人だけ3タブのインデントを使ったのでは意味がありません。
コーディング規約の遵守に役立つツールは多数存在します。
そうしたツールには、規約をドキュメント化する機能、規約からの逸脱を報告する機能などがあります。
ただし、そういうツールを使えば問題が全て解決するわけではありません。

コーディング規約は可能な限り、自動的、かつ強制的に守られるようにすべきでしょう。
具体的には次のような方法が有効です。

コードの整形処理をビルドプロセスに含めてしまう。
コードのコンパイルをする度に、誰もが必ず、自動的に整形することになる。
静的なコード解析ツールを使用してコードを解析し、望ましくないアンチパターンがないかを探す。もし見つかれば、ビルドを中止する。
ツールの設定により、プロジェクト固有のアンチパターンも見つけ出せるようにする。
テストカバレッジをただ計測するだけで終わらせるのではなく、
計測結果の判定も自動的に行われるようにする。
そしてテストカバレッジが低すぎる場合は、ビルドを中止する。

以上のことを、重要なプロジェクトでは必ず実践するようにするのです。

コーディング規約を自動化する

今回作ったAndroidCoverageCheckプラグインが少しでも皆様のお役に立てれば幸いです。
AndroidCoverageCheckプラグインは先程公開したばかりで、不具合等あるかもですが、これからチームでも導入し、カバレッジを高めていくためのツールとして使い込んでいきたいと考えているので、何卒よろしくお願いします:bow:
どこか既視感のある、まとめとなってしまいました