Как предотвратить androidx.AndroidJUnitRunner от сканирования классов на пути к классам и сбоя с NoClassDefFoundError? - PullRequest
0 голосов
/ 23 марта 2020

У меня есть проект Android и новый библиотечный модуль, для которого я пишу androidTest тесты. Эти тесты запускаются в Android Studio, но выполняются sh на CI или на консоли при запуске gradlew connectedCheck.

Gradle сообщает, что тесты не найдены:


I/RemoteAndroidTest: Running CLASSPATH=$(pm path androidx.test.services) app_process / androidx.test.services.shellexecutor.ShellMain am instrument -r -w -e targetInstrumentation de.myapp.test/androidx.test.runner.AndroidJUnitRunner --no_window_animation  -e coverageFilePath /data/data/de.myapp.test/coverage_data/ -e coverage true -e disableAnalytics true androidx.test.orchestrator/androidx.test.orchestrator.AndroidTestOrchestrator on Pixel_2_API_28(AVD) - 9
V/ddms: execute: running CLASSPATH=$(pm path androidx.test.services) app_process / androidx.test.services.shellexecutor.ShellMain am instrument -r -w -e targetInstrumentation de.myapp.test/androidx.test.runner.AndroidJUnitRunner --no_window_animation  -e coverageFilePath /data/data/de.myapp.test/coverage_data/ -e coverage true -e disableAnalytics true androidx.test.orchestrator/androidx.test.orchestrator.AndroidTestOrchestrator
V/InstrumentationResultParser: INSTRUMENTATION_RESULT: stream=
V/InstrumentationResultParser:
V/InstrumentationResultParser: Time: 0
V/InstrumentationResultParser:
V/InstrumentationResultParser: OK (0 tests)
V/InstrumentationResultParser:
V/InstrumentationResultParser:
V/InstrumentationResultParser: INSTRUMENTATION_CODE: 0
V/InstrumentationResultParser:
Starting 0 tests on Pixel_2_API_28(AVD) - 9
I/XmlResultReporter: XML test result file generated at C:\Workspace\myapp\build\outputs\androidTest-results\connected\TEST-Pixel_2_API_28(AVD) - 9-myapp-.xml. Total tests 0,
V/ddms: execute 'CLASSPATH=$(pm path androidx.test.services) app_process / androidx.test.services.shellexecutor.ShellMain am instrument -r -w -e targetInstrumentation de.myapp.test/androidx.test.runner.AndroidJUnitRunner --no_window_animation  -e coverageFilePath /data/data/de.myapp.test/coverage_data/ -e coverage true -e disableAnalytics true androidx.test.orchestrator/androidx.test.orchestrator.AndroidTestOrchestrator' on 'emulator-5554' : EOF hit. Read: -1
V/ddms: execute: returning

com.android.builder.testing.ConnectedDevice > No tests found.[Pixel_2_API_28(AVD) - 9] 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).

Тест сам по себе является обычным модульным тестом, который использует Android классов (android .os.Bundle) и работает в Android Studio.

В выводе logcat я вижу подозрительные ошибки, которые, вероятно, заставляют его думать, что тестов нет:

W/AndroidJUnit4Builder: java.lang.NoClassDefFoundError: Failed resolution of: Lde/library/ITimeSource; in hasTestMethods for de.library.DaggerComponent
 Rejecting re-init on previously-failed class java.lang.Class<de.library.MyModule_StuffFactory>: java.lang.NoClassDefFoundError: Failed resolution of: Ldagger/internal/Factory;
     at java.lang.Class java.lang.Class.classForName(java.lang.String, boolean, java.lang.ClassLoader) (Class.java:-2)
     at java.lang.Class java.lang.Class.forName(java.lang.String, boolean, java.lang.ClassLoader) (Class.java:453)
     at void androidx.test.internal.runner.TestLoader.doCreateRunner(java.lang.String, boolean) (TestLoader.java:72)
     at java.util.List androidx.test.internal.runner.TestLoader.getRunnersFor(java.util.Collection, boolean) (TestLoader.java:104)
     at org.junit.runner.Request androidx.test.internal.runner.TestRequestBuilder.build() (TestRequestBuilder.java:793)
     at org.junit.runner.Request androidx.test.runner.AndroidJUnitRunner.buildRequest(androidx.test.internal.runner.RunnerArgs, android.os.Bundle) (AndroidJUnitRunner.java:547)
     at void androidx.test.runner.AndroidJUnitRunner.onStart() (AndroidJUnitRunner.java:368)
     at void android.app.Instrumentation$InstrumentationThread.run() (Instrumentation.java:2145)
 Caused by: java.lang.ClassNotFoundException: Didn't find class "dagger.internal.Factory" on path: DexPathList[[zip file "/system/framework/android.test.mock.jar", zip file "/system/framework/android.test.runner.jar", zip file "/data/app/myapp.test-pT5x5OKGnhH6aNlSdAfVHA==/base.apk"],nativeLibraryDirectories=[/data/app/myapp.test-pT5x5OKGnhH6aNlSdAfVHA==/lib/x86, /data/app/myapp.test-pT5x5OKGnhH6aNlSdAfVHA==/base.apk!/lib/x86, /system/lib]]
     at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:134)
     at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean) (ClassLoader.java:379)
     at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:312)
     at java.lang.Class java.lang.Class.classForName(java.lang.String, boolean, java.lang.ClassLoader) (Class.java:-2)
     at java.lang.Class java.lang.Class.forName(java.lang.String, boolean, java.lang.ClassLoader) (Class.java:453)
     at void androidx.test.internal.runner.TestLoader.doCreateRunner(java.lang.String, boolean) (TestLoader.java:72)
     at java.util.List androidx.test.internal.runner.TestLoader.getRunnersFor(java.util.Collection, boolean) (TestLoader.java:104)
     at org.junit.runner.Request androidx.test.internal.runner.TestRequestBuilder.build() (TestRequestBuilder.java:793)
     at org.junit.runner.Request androidx.test.runner.AndroidJUnitRunner.buildRequest(androidx.test.internal.runner.RunnerArgs, android.os.Bundle) (AndroidJUnitRunner.java:547)
     at void androidx.test.runner.AndroidJUnitRunner.onStart() (AndroidJUnitRunner.java:368)
     at void android.app.Instrumentation$InstrumentationThread.run() (Instrumentation.java:2145)

Таким образом, он не может загрузить класс Dagger2, который не находится в пути к классам. Этот библиотечный модуль имеет несколько нетранзитивных зависимостей, включая Dagger2, который мне не нужен. Только некоторые из классов этой библиотеки имеют эти зависимости, и они не используются моим модулем . Эта зависимость объявлена ​​с помощью isTransitive = false:

dependencies {
  implementation("de.company:library:version") { isTransitive = false }
}

Мне кажется, что androidx.test.runner.AndroidJUnitRunner сканирует все классы, присутствующие в пути к классам, и сканирует их для методов тестирования. Это терпит неудачу, потому что некоторые классы (которые не используются) ссылаются на классы, которые не доступны на пути к классам. Я прав? Если да, как я могу предотвратить это поведение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...