始めに
以前にも少しメモで書いたりしたが、Androidのアプリ開発でEclipseを使っている場合にAndroid標準のAndroid Test Projectを使っているとカバレッジを確認できない。個人的には、これがかなりUnit Testへのモチベーションを下げているのではないかと考えた。
よろしくない話ではあるが、実際現場のプロダクトでAndroid Test Projectを作成しようとしたときに、どこまでUnit Testを書き込むか悩む場面が多かった。
そして、結局時間を言い訳に、ろくにUnit Testは行なわず、、、となる。
それへの自戒も含め、どのようにUnit Testの進捗を管理し、モチベーションを維持するか、というテーマで取り組んだのが今回の内容。
今回のゴール
- Android Test ProjectでUnit Testを実施する。
- Jenkinsにより、Unit Testを継続的に自動実行する。
- Unit Testを実施した結果のカバレッジを、簡単に参照できる。
- カバレッジは、極力開発中にも確認したい。
Androidのビルドシステムの中にEmmaというカバレッジ集計ライブラリがあり、これを使うことでUnit Testのカバレッジ集計を行なう。ただし、これを有効にするためにはAntによるビルドが必要である。
JenkinsにはEmma Pluginというものがあり、JenkinsでAndroidプロジェクトをビルドするにはAntで行なわないといけないため、Jenkins内でのカバレッジ集計結果の確認(2.、3.)は難しくない。
しかし、通常開発はEclipseで行なっているため、これではカバレッジの確認ができない。そのため、gitのhooksを併用し、ローカルのgitリポジトリへのコミット時にAntビルドを行なってカバレッジ集計を行なうようにした。
環境
- プロダクトの開発はEclipse 4.2 + Android SDK r22 (Mac OS X 10.8.x)
- GitはBitbucketのプライベートリポジトリを使用
- JenkinsサーバはレンタルVPS (Ubuntu 12.04 64bit / Android向けの環境構築が楽なので)
Gitリポジトリは、最近よく使わせてもらっているBitbucketのプライベートリポジトリを使用した。
BitbucketへのpushをhookしてJenkinsで自動ビルドを行ないたかったので、Jenkinsサーバもパブリックな場所に設置した。
開発ターゲット
ゴールの達成を目標として、新規でAndroidアプリを開発した。
開発時の流れ
実際は色々と試行錯誤を繰り返して、上記の環境と以下の手順に落ち着いた。
- プロダクトコードの記述
- ビルドが通ることを確認しコミット
- Unit Testの記述
- テスト実行しNGが無い事を確認してコミット
- カバレッジ確認
- 一通りカバーできていればpush
- Jenkinsサーバでの自動ビルド結果を確認
以下、各手順での具体的な雰囲気。
プロダクトコードの記述
地道に頑張る。
ビルドが通ることの確認しコミット
この時点でGitのhooksでカバレッジが表示されるので、コミット後にカバレッジが下がっていることが確認できる。
Unit Testの記述
地道に頑張る。
カバレッジ確認して不足した箇所があれば、そこを中心に記述。
テスト実行しNGが無い事を確認してコミット
テスト実行はEclipseで楽々。
問題なければテストコードのコミット。
コミットでカバレッジ集計されるように、Gitとの連動を行なっておく。(スクリプトは付録で。)
カバレッジ確認
コミット後にカバレッジ確認し、新規追加したプロダクトコードがカバーされていることを確認する。
不足していたら、Unit Testの記述に戻る。
ちなみに、Antでビルド後はEclipseのビルドで色々不具合が出るので、コミット時の実行スクリプトで"bin"と"gen"のクリアも実行する。
一通りカバーできればpush
プッシュプッシュ。
Jenkinsサーバでの自動ビルド結果を確認
JenkinsのAndroidプラグインで、手元で行なったことと同等のことがCIサーバ上で行なわれる。
が、Android Emulatorの起動に時間がかかるので、ここは少しネックか。
(Emulatorを別途起動できていれば、問題ないかも?)
まとめ
当初の目標は達成できたのか
少なくとも個人での開発であれば、カバレッジの具体的な内容を見る事で、Unit Testの進捗をある程度管理は可能だと感じた。
また、カバーすべき箇所も具体的になるので、Unit Testの内容も考えやすくなる。
上記がクリアになることで、個人としてはだいぶモチベーションを上げてUnit Testに取り組む事が出来た。
個人的には目標を達成できたので、引き続き今回の手順をさらに良くしていきたい。
今後の課題
今回は、"Unit Test"を書く事を主眼としていたため、AndroidのUI周りのテストコードについては、十分には書いていない。
今後は、ライブラリを取り入れるなどして、こちらも組み入れているようにしたい。
また、Jenkinsサーバでのテスト実行に時間がかかっているので、こちらの解消も可能か確認しておきたい。
後は、新しい開発環境であるAndroid Studioではどうなるかも、確認が必要。
付録: git commit時に連動して実行されるスクリプト
以下のファイルを作成することで、コミット実行ごとにGoogle Chromeでカバレッジ集計結果を表示することができる。
ディレクトリ構成については、各自のプロジェクトに合わせる。
ブラウザとの連携はOSごとに異なると思うので、適宜読み替え。
#!/bin/sh
ANDROID_DIR=${HOME}/android-sdk-macosx/
ANDROID=${ANDROID_DIR}/tools/android
BASE_DIR=${HOME}/repo/bitbucket/PROJECT_NAME
PRODUCT=PROJECT_NAME
TEST_PRJ=android/TEST_PROJECT_NAME
${ANDROID} update project -p ${BASE_DIR}/${PRODUCT}
${ANDROID} update test-project -m ../../${PRODUCT} -p ${BASE_DIR}/${TEST_PRJ}
ant -f ${BASE_DIR}/${TEST_PRJ}/build.xml clean emma debug install test
cp ${BASE_DIR}/${TEST_PRJ}/bin/coverage.html /tmp
open -a "Google Chrome" /tmp/coverage.html
rm -rf ${BASE_DIR}/${PRODUCT}/bin/
rm -rf ${BASE_DIR}/${PRODUCT}/gen/
rm -rf ${BASE_DIR}/${TEST_PRJ}/bin/
rm -rf ${BASE_DIR}/${TEST_PRJ}/gen/