Help us understand the problem. What is going on with this article?

最新のRobolectric (v4.3)の導入で迷える子羊を俺が救う[ Android / testing ]

Robolectric

これ is 何

Androidのテスト環境のRobolectric v4.3 の導入を紹介する記事です。

Robolectric v4.0以降大幅に書き方が変化したもののそれに対応していない記事が多く、
今新規に導入をしようとした場合には半端なレベルの日本語作業者は全員地獄を見ると思ったので、
次なる犠牲者を出さないためにも記事にすることにしました。ちなみに僕は地獄を見ました。

環境

AndroidStudio : 3.4.1
CompleSdkVersion : 26
Programming Language : Kotlin (最後のテストコードのサンプルだけです)

手順

ビルド設定関連

書いてあるところ : Robolectric GETTING-STARTED

module-name/build.gradle
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'
    // espressoしたかったりしたらそれも入れる
}
gradle.properties
  // 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関連のテストができました。

既知の不具合(踏んだもの)

おわりに

つらかった方の話。
https://nanoyatsu.hatenadiary.jp/entry/2019/06/15/052936

happy testing !

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away