heihei blog

Blog icon by Unsplash https://unsplash.com/@virussinside

AS3.0-stable + RobolectricによるUnitテストでResourceNotFoundExceptionが出る際の対策

バージョンは下記:

現象はタイトルの通りで、上記バージョンのAndroidとRobolectricを使ってUnitテストを実行すると、AndroidのResourcesにアクセスする際にResourceNotFoundExceptionが発生しテストが失敗するというものです。(ちなみに自分の場合は、ローカルでの実行は正常に動きCI(Bitrise)上での実行時のみ失敗する、というものでした。)

あくまで自分のケースのみ有効かもしれませんが、下記に解決策を紹介します:

ResourceNotFoundExceptionに対する解決策

app/build.gradleandroid {}内にtestOptionsを追加し、Unitテスト実行時の設定を記述します。

testOptions {
  unitTests {
    includeAndroidResources = true
  }
}

includeAndroidResourcesに関するドキュメントは下記です: UnitTestOptions - Android Plugin 3.0.0-dev DSL Reference

このoptionをtrueにすることで、Unitテストの実行前にアセット、リソースやマニフェストのマージをプラグインが行ってくれるそうです。

これを指定することでResourceNotFoundExceptionを防ぎテストを正常に実行できるようになりました。

(テスト実行時にthreetenbpに依存している場合の)ZoneRulesExceptionに対する解決策

includeAndroidResourcesオプションを設定することで大半のテストは正常に実行されるようになったのですが、今度は下記のようなエラーログが出てテストが終了するという現象がありました。

    org.threeten.bp.zone.ZoneRulesException
    at android.net.LocalSocketImpl.bind(LocalSocketImpl.java:303)
    at android.net.LocalServerSocket.__constructor__(LocalServerSocket.java:48)
    at android.net.LocalServerSocket.<init>(LocalServerSocket.java)
    at com.facebook.stetho.server.LocalSocketServer.bindToSocket(LocalSocketServer.java:142)
    at com.facebook.stetho.server.LocalSocketServer.listenOnAddress(LocalSocketServer.java:78)
    at com.facebook.stetho.server.LocalSocketServer.run(LocalSocketServer.java:74)
    at com.facebook.stetho.server.ServerManager$1.run(ServerManager.java:40)

アプリではThreeTenABPを利用しているのですが、

IllegalStateException: TZDB.dat missing from assets

というエラーログと共にテストが実行できないことに過去に悩まされた結果、

参考: IllegalStateException: TZDB.dat missing from assets · Issue #24 · JakeWharton/ThreeTenABP · GitHub

上記issueに記載されている解決策を元にテスト実行時にはThreeTenBPに依存するようにしていました。今回ZoneRulesExceptionが出たタイミングでこの依存を試しに解消してみたところテストが正常に通ることがわかりました。(oh..)

予想としてはincludeAndroidResourcesが影響しているものと思っているのですが、具体的なところまでは調査できていません。

下記に今回調査する際にお世話になったサイト一覧を記載しておきます。雑ですが、以上です!