Robolectric (v4.3)の導入で迷える子羊を俺が救う[ Android / testing ]
記事の初版からだいたい一年が経ちました
(特にセットアップ関係は)ここを見たほうがよいと思います。
Android Developers > ドキュメント > ガイド > 「ローカル単体テストを作成する」
https://developer.android.com/training/testing/unit-testing/local-unit-tests?hl=ja
依存関係系はページの先頭に書いてあって、実際のコードはフレームワークの依存関係を含めるあたりです。
java.lang.IllegalStateException: No instrumentation registered!
で怒られたらAndroid Gradle Pluginを見直してみてくださいね。
https://stackoverflow.com/questions/53595837/androidx-no-instrumentation-registered-must-run-under-a-registering-instrumen
よいテストライフを👋
これ is 何
Androidのテスト環境のRobolectric v4.3 の導入を紹介する記事です。
Robolectric v4.0以降大幅に書き方が変化したもののそれに対応していない記事が多く、
今新規に導入をしようとした場合には半端なレベルの日本語作業者は全員地獄を見ると思ったので、
次なる犠牲者を出さないためにも記事にすることにしました。ちなみに僕は地獄を見ました。
手順
ビルド設定関連
書いてあるところ : Robolectric GETTING-STARTED
android {
// ほかにも書いてある
sourceSets {
// ↓無ければ追記
test.java.srcDirs += 'src/test/java'
androidTest.java.srcDirs += 'src/androidTest/java'
}
testOptions {
unitTests {
includeAndroidResources = true
returnDefaultValues = true
}
}
}
dependencies{
// ほかにも書いてある
testImplementation 'androidx.test:core:1.2.0'
testImplementation 'androidx.test:runner:1.2.0'
testImplementation 'androidx.test:rules:1.2.0'
testImplementation 'androidx.test.ext:junit:1.1.1'
testImplementation 'androidx.test.ext:truth:1.2.0'
testImplementation 'com.google.truth:truth:0.42'
testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:4.3'
}
# androidStudio 3.3以上では不要
android.enableUnitTestBinaryResources=true
ここまでで環境の整備は完了です。かんたん!
テストの記述
手作業でも AndroidStudio のCreate Test
でもよいので、テストのファイルを用意します。(test.java.srcDirs
のほうのディレクトリです!)
ここで色々書いていくわけですが、公式を参考にするだけでは書ききれなかったりと、ハマりポイントでした。
テストランナー
@RunWith(AndroidJUnit4::class)
v4.0以降を使うのであれば、たぶんandroidxを使わない手はないと思うのでAndroidJUnit4です。
Robolectricのものと自動で切り替わります。
Contextの取得
ApplicationProvider.getApplicationContext()
InstrumentationRegistryは使用しません。
ActivityScenarioの取得
val scenario = launch<CountActivity>(startActivityIntent)
例
実際の実装からいくらか切り抜いて例としているので半端になってしまうのですが、
こんな感じ↓のダイアログのイメージです。まさかの文字列表現。
タイトル文字列
[-][+][ 5]
各ViewのIDはtitleText
,buttonMinus
,buttonPlus
,count
。
機能は
- 数値をカウントアップ・ダウンする
- Intent経由で以下の値を渡せる
- タイトル文字列
IntentKey.TITLE_TEXT
(String) - 現在値
IntentKey.COUNT
(Int) - 最小値
IntentKey.LOWEST_COUNT
(Int)
- タイトル文字列
@RunWith(AndroidJUnit4::class)
@Config(sdk = [Build.VERSION_CODES.O]) // 動作対象バージョンの指定ができます
class CountActivityTest {
@Test fun onClickCount() {
val startActivityIntent = Intent(ApplicationProvider.getApplicationContext(), CountActivity::class.java).also{
it.putExtra(CountActivity.IntentKey.TITLE_TEXT.name,"TEST_TITLE")
it.putExtra(CountActivity.IntentKey.COUNT.name, 3)
it.putExtra(CountActivity.IntentKey.LOWEST_COUNT.name, 0)
}
val scenario = launch<CountActivity>(startActivityIntent)
scenario.moveToState(Lifecycle.State.CREATED) // Activityの状態をCreatedにする=onCreate()後の状態
scenario.onActivity {
assertNotEquals(it.titleText.text, "ERROR_TITLE")
assertEquals(it.titleText.text, "TEST_TITLE")
assertEquals(it.count.text, "3")
assertNotEquals(it.count.text, "2")
it.buttonMinus.performClick()
assertEquals(it.count.text, "2")
it.buttonMinus.performClick()
it.buttonMinus.performClick()
assertEquals(it.count.text, "0")
it.buttonMinus.performClick()
assertEquals(it.count.text, "0")
it.buttonPlus.performClick()
assertEquals(it.count.text, "1")
}
}
}
JVM上でActivity関連のテストができました。
既知の不具合(踏んだもの)
-
java 9 warnings (illegal reflective access operation) #4776
- 怒られます。(怒られるだけ)
-
Fix remaining usages of ByteBuffer.position(int) #5075
- 自分が対象としたプロジェクトでは、Applicationクラスを継承したクラスの初期化処理中でTimes.javaが例外を吐きました。
- Robolectric4.4では修正されています。
- このエラーかな・・・?と思ったときにはgithubページのトップ最下段にある、
SNAPSHOTバージョンの利用を試してみるとよいかもしれません。
それで直ったら、近々リリースされるであろう次バージョンを待ちましょう。4.3の導入記事じゃないのかよ
おわりに
なかなかv4.4のリリースありませんね・・・(2020.04.23)
happy testing !
Author And Source
この問題について(Robolectric (v4.3)の導入で迷える子羊を俺が救う[ Android / testing ]), 我々は、より多くの情報をここで見つけました https://qiita.com/nanoyatsu/items/cc2af0d792fad74afe2d著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .