背景・目的
テストカバレッジを自動取得する方法を調査していたところ、 Codecov というテストカバレッジ取得 CI サービスがあることを知りました。
早速、 Android テストのカバレッジを取得する Codecov のサンプルコード を確認したところ、 Travis CI 上で Android エミュレータが起動できず build error の状態でした。
The command "./gradlew build jacocoTestReport assembleAndroidTest" exited with 0.
$ echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI
Error: Target id is not valid. Use 'android list targets' to get the target ids.
The command "echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI" exited with 1.
Android エミュレータを起動しないと実行できないテストがあるため、 Android エミュレータが起動できるよう、サンプルコードを修正しました。
Android エミュレータとインストルメント化されたテスト
Android には、次の 2 つのタイプのテストがあります。1
- ローカル ユニット テスト / Local unit tests
- インストルメント化されたテスト / Instrumented tests
うち、インストルメント化されたテストについては、それを実行するために Android エミュレータが必要です。
(ローカル環境では、ハードウェア端末を接続してテスト実行することも可能です。)
2 つのタイプのテストの違いについては割愛しますが、 Context を参照するテストではインストルメント化されたテストを実装する必要があります。
サンプルでエミュレータが起動できない原因
前述のエラーログには Target id is not valid.
とありますが、これはエミュレータと同じ API level の Android SDK Platform がインストールされていない場合に表示されるエラーログです。
language: android
jdk: oraclejdk8
env:
global:
- ANDROID_TARGET=android-15 # エミュレータは API level 15 を指定
- ANDROID_ABI=armeabi-v7a
android:
components:
- tools
- platform-tools
- build-tools-23.0.3
- android-23 # しかし、インストールする Android SDK Platform は API level 23 のみ
- extra-android-m2repository
- sys-img-${ANDROID_ABI}-${ANDROID_TARGET}
script:
- ./gradlew build jacocoTestReport assembleAndroidTest
- echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI
- emulator -avd test -no-skin -no-audio -no-window &
- android-wait-for-emulator
- adb shell setprop dalvik.vm.dexopt-flags v=n,o=v
- ./gradlew connectedCheck
after_success:
- bash <(curl -s https://codecov.io/bash)
以上から、 .travis.yml
の components
に android-15
を追記すれば解決すると考えましたが、これだけではエミュレータを起動することはできませんでした。
エラーログは表示されませんが、エミュレータが起動できない状態が 10 分以上続きタイムアウトします。この現象については詳細不明です。
Travis CI 上で起動できる Android エミュレータについて
Travis CI の公式には、次のように記載されています。
Warning: At the moment, these steps are not fully supported by Travis CI Android builder.
(警告:現時点では、これらの手順はTravis CI Android Builderによって完全にはサポートされていません。)If you feel adventurous, you may use the script
/usr/local/bin/android-wait-for-emulator
and adapt your.travis.yml
to make this emulator available for your tests.
(あなたが冒険的であると感じるならば、あなたはスクリプト/usr/local/bin/android-wait-for-emulator
を使い、あなたのテストのためにこのエミュレータを利用できるようにあなたの.travis.yml
を適応させることができます。)For example:
.travis.yml# Emulator Management: Create, Start and Wait before_script: - echo no | android create avd --force -n test -t android-22 --abi armeabi-v7a - emulator -avd test -no-audio -no-window & - android-wait-for-emulator - adb shell input keyevent 82 &
example に従い、 API level 22 の Android エミュレータを指定したところ、エミュレータを無事起動することができました。 Travis CI 上での Android エミュレータの起動は完全にはサポートされないが、 API level 22 のエミュレータであれば比較的安定して起動できるということでしょうか?残念ながら、これ以上の公式ドキュメントは見つけられず、具体的にサポートされる内容は不明です。
Codecov によるテストカバレッジ取得
ここまでの手順により、 Android エミュレータの起動に成功しました。これにより、サンプルの Android テストを Pass することができ、サンプルコード修正のプルリクエストへ Codecov からカバレッジが通知されました。サンプルコードはシンプルなため、テストカバレッジは 100% です。
結論
diff --git a/.travis.yml b/.travis.yml
index 9a8faee..e665b4a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,7 @@ language: android
jdk: oraclejdk8
env:
global:
- - ANDROID_TARGET=android-15
+ - ANDROID_TARGET=android-22 # エミュレータは API level 22 を指定する
- ANDROID_ABI=armeabi-v7a
android:
components:
@@ -11,6 +11,7 @@ android:
- build-tools-23.0.3
- android-23
- extra-android-m2repository
+ - $ANDROID_TARGET # エミュレータと同じ API level の Android SDK Platform をインストールする
- sys-img-${ANDROID_ABI}-${ANDROID_TARGET}
script:
- ./gradlew build jacocoTestReport assembleAndroidTest
今後について
今回は Codecov のサンプルにならって Travis CI 上で Android エミュレータを起動、テスト実行、カバレッジ取得をしました。有名な CI サービスは Travis CI だけでなく CircleCI などがあります。利用できるエミュレータが API level 22 だけでは困ることが起こり得るので、他の CI サービスを利用することで解決を図りたいです。