LoginSignup
16
7

More than 3 years have passed since last update.

Mutlidexを使ってる時にAndroidTestが動かない問題とその対処方法

Last updated at Posted at 2018-04-27

お久しぶりです。くぎみやです。

問題発覚

AndroidKeyStore を使っていて、 encrypt して decrypt できるかのテストを書こうと思いました。特にここら辺はHWも関わってくるところであるために、モックなど使わずにサボらずに実機 (or エミュレータ)でテストを書こうと思ったのが始まりでした。

encrypt したものを decrypt し、元のテキストになるかのテストを書き、 Android8.1のエミューレータで動かしたところ、テストはしっかり動きました。そして、いくつか修正して最終的に SUCCESSの文字がターミナルにでて来ました。

いつもであればこれで良しとするのですが、 AndroidKeyStore周りのAPIがAndroid6.0から結構変わっておりまして、そのためminSDKのバージョンに指定しているAndroid4.3でも試して見たところ問題が発生しました。

com.android.builder.testing.ConnectedDevice > No tests found.[Nexus_5X_API_18(AVD) - 4.3.1] FAILED 
No tests found. This usually means that your test classes are not in the form that your test runner expects (e.g. don't inherit from TestCase or lack @Test annotations).

ちなみに、AS上からテストファイルを開いて、テストクラスの左側に表示されてる単体実行のボタンを押すと、ちゃんと実行されて成功するんですよね...

そのときの build.gradle

build.gradle
android {

    defaultConfig {
        :
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        multiDexEnabled true
    }
    :
}
dependencies {
    :
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

これで、少なくともAndroid8.1のエミューレータではしっかり動くことを確認しています。

原因

The issue is that the main dex list for the test APK does not contain the test classes. AndroidJUnitRunner when looking for the test classes, does not uses the patched class loader that contains all dex files, but it only examines classes.dex. Therefore, it does not find any test classes to run.

ここに書いてあることが全てなのですが、補足しておくと AndroidJUnitRunnerclasses.dex しか見てくれない、つまり classesN.dex などが無視されてしまうことが問題のようです。

mutlidexをtureにしているときは、こんな感じで複数のdexファイルができます。

スクリーンショット 2018-04-27 12.33.28.png

肝心のテストクラスを探してみると、 classes2.dex の中にあることがわかります。

スクリーンショット 2018-04-27 12.39.41.png

AndroidJUnitRunnerclasses2.dex は見ずに、 classes.dex しか見てくれない。
よって No tests found. ということらしいです。

解決策

先ほどと同じリンクにworkaroundも書かれています。

android.enableD8MainDexList=false

as this will make as keep all annotated classes in the main dex. Even though that is not the required for the legacy multidex to work, it will fix the issue for this particular case.

gradle.propertiesandroid.enableD8MainDexList=false と記述することで解消するようです。

これを記述することで、アノテーション付きのクラスをmainのdexファイルに入れたままにできるそうです。

試して見たところ、 build.gradle に下記も必要でした。

build.gradle
dependencies {
  : 
  androidTestImplementation 'com.android.support:multidex-instrumentation:1.0.3'
}

ここまでやって、ようやくAndroid4.3でもテストを通すことができました。

確認

念のため、 keep all annotated classes in the main dex これも確認しておきましょう。

スクリーンショット 2018-04-27 12.49.03.png

なるほど、たしかに classes.dex にてテストクラスを発見することができました。

まとめ

multidex時にandroidTestを動かしたいなら、こんな感じ。

build.gradle
android {

    defaultConfig {
        :
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        multiDexEnabled true
    }
    :
}
dependencies {
    :
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    androidTestImplementation 'com.android.support:multidex-instrumentation:1.0.3'
}
gradle.properties
:
android.enableD8MainDexList=false
16
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
7