安卓测试无法在低于5的设备上运行(API 21以下),出现NoClassDefFoundError错误。

5

我正在尝试为我的项目运行仪器测试。但是它们无法在版本低于5(API 21)的设备(模拟器也一样)上运行。

我一直在努力解决这个问题,但仍然面临着它。我收到以下异常信息。

02-15 10:46:08.965 1127-1143/? E/AndroidRuntime: FATAL EXCEPTION: Instr: android.support.test.runner.AndroidJUnitRunner
                                                 java.lang.ExceptionInInitializerError
                                                     at android.support.test.internal.runner.TestRequestBuilder.<init>(TestRequestBuilder.java:81)
                                                     at android.support.test.internal.runner.TestRequestBuilder.<init>(TestRequestBuilder.java:524)
                                                     at android.support.test.runner.AndroidJUnitRunner.createTestRequestBuilder(AndroidJUnitRunner.java:379)
                                                     at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:352)
                                                     at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:269)
                                                     at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1584)
                                                  Caused by: java.lang.NoClassDefFoundError: org.junit.runner.manipulation.Filter$1
                                                     at org.junit.runner.manipulation.Filter.<clinit>(Filter.java:21)
                                                     at android.support.test.internal.runner.TestRequestBuilder.<init>(TestRequestBuilder.java:81) 
                                                     at android.support.test.internal.runner.TestRequestBuilder.<init>(TestRequestBuilder.java:524) 
                                                     at android.support.test.runner.AndroidJUnitRunner.createTestRequestBuilder(AndroidJUnitRunner.java:379) 
                                                     at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:352) 
                                                     at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:269) 
                                                     at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1584

我已经尝试了所有类似问题的解决方案。

这是我的项目结构。

project structure

测试用gradle依赖

  /************* TEST STUFF ***************/
    androidTestCompile 'junit:junit:4.12'
    androidTestCompile fileTree(include: ['robotium-solo-5.5.2.jar'], dir: 'libs')
    //mockito dependencies
    androidTestCompile 'org.mockito:mockito-core:2.7.6'
    androidTestCompile files('libs/dexmaker-mockito-1.0.jar')
    androidTestCompile files('libs/dexmaker-1.0.jar')

    // Set this dependency to build and run Espresso tests
    androidTestCompile('com.android.support.test.espresso:espresso-core:+') {
        exclude group: 'com.android.support', module: 'support-annotations'
    }

    androidTestCompile('com.android.support.test:runner:0.5') {
        exclude group: 'com.android.support', module: 'support-annotations'
    }
    // Set this dependency to use JUnit 4 rules
    androidTestCompile('com.android.support.test:rules:+') {
        exclude group: 'com.android.support', module: 'support-annotations'
    }
    androidTestCompile('com.android.support.test.espresso:espresso-intents:+') {
        exclude group: 'com.android.support', module: 'support-annotations'
    }
    //MockWebServer - Version 2.2 of mockwebserver doesn't work because of an issue, so forcing v2.1 - https://github.com/square/okhttp/issues/1069
    androidTestCompile('com.squareup.okhttp3:mockwebserver:+') {
        exclude module: 'okhttp'
    }
    androidTestCompile "org.slf4j:slf4j-api:1.7.12"
    //WireMock
    androidTestCompile("com.github.tomakehurst:wiremock:2.5.0") {
        //Using Android Version Instead
        exclude group: 'org.apache.httpcomponents', module: 'httpclient'

        //Version conflict with our app's slf4j version
        exclude group: 'org.slf4j', module: 'slf4j-api'

        //Was getting a classpath conflict for org.objectweb.asm.AnnotationVisitor which is a part of 'net.minidev:asm'
        exclude group: 'org.ow2.asm', module: 'asm'

        //Was getting this warning, so decided to ignore this version included by WireMock.
        //Warning:Dependency org.json:json:20090211 is ignored as it may be conflicting with the internal version provided by Android.
        //In case of problem, please repackage with jarjar to change the class packages
        exclude group: 'org.json', module: 'json'
    }
    androidTestCompile 'org.apache.httpcomponents:httpclient-android:4.3.5.1'

BaseTestClass 的结构如下:

@RunWith(AndroidJUnit4.class)
public abstract class InstrumentalSuperTest {

    private SystemAnimations mSystemAnimations;

    @Rule
    public IntentsTestRule rule = provideActivity();

    @Rule
    public WireMockRule wireMockRule = new WireMockRule(WireMockConfiguration.wireMockConfig().port(BuildConfig.PORT), false);

    protected abstract IntentsTestRule provideActivity();

}

这不仅发生在我的项目中,也发生在Wiremock examples中,出现了相同的错误。
可能是我测试的方式不正确,我只是点击一个测试类并选择运行...测试
请帮忙解决这个问题,我不知道出了什么问题。

provideActivity() 是自定义方法吗?你能提供它的内容吗? - sebokopter
尝试在您的风格配置中定义一个multiDexKeepProguard文件('../proguardRules/multidex-proguard.pro'),并在该文件中使用类似于proguard的语法来保留您在测试中找不到的类。有时候,在测试运行中正确地使用multidex是非常困难的。 - originx
测试仪器 APK 在 Lollipop 之前无法进行多 dex,即使您尝试也不行。WireMock 具有巨大的方法计数占用空间,我猜测您的测试 APK 已经进行了 multidex 处理。第一个 dex 文件将被选中,但是在后续的 dex 文件中的任何内容都将无法使用,如果您尝试访问其他 dex 文件中的任何类,则会出现 ClassNotFoundException。 - Sam Edwards
你找到解决方案了吗? - Day
1个回答

1
你可以尝试使用新版本的WireMock,该版本应该是2.0.8-beta之后的版本。 要了解更多信息,请查看stackoverflow答案

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接