【问题标题】:NoClassDefFoundError when running Gradle connectedCheck on AVD emulator在 AVD 模拟器上运行 Gradle connectedCheck 时出现 NoClassDefFoundError
【发布时间】:2015-09-16 08:28:59
【问题描述】:

我正在尝试为 Android 应用运行 Espresso 测试。它在硬件设备上运行良好。当我在新创建的 AVD 模拟器 上运行它时,它失败,如下所示:

:ExampleApp:connectedDebugAndroidTest

com.example.MainFragmentTest > initializationError[Nexus_5_API_19(AVD) - 4.4.2] 
FAILED 
    java.lang.NoClassDefFoundError: com/example/MainActivity
    at java.lang.Class.getDeclaredFields(Native Method)
:ExampleApp:connectedDebugAndroidTest FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':ExampleApp:connectedDebugAndroidTest'.
> There were failing tests. See the report at: 
file:///home/user/work/ExampleApp/build/reports/androidTests/connected/index.html

HTML 报告包含以下堆栈跟踪:

java.lang.NoClassDefFoundError: com/example/MainActivity
at java.lang.Class.getDeclaredFields(Native Method)
at java.lang.Class.getDeclaredFields(Class.java:610)
at org.junit.runners.model.TestClass.getSortedDeclaredFields(TestClass.java:77)
at org.junit.runners.model.TestClass.scanAnnotatedMembers(TestClass.java:70)
at org.junit.runners.model.TestClass.<init>(TestClass.java:57)
at org.junit.runners.ParentRunner.createTestClass(ParentRunner.java:88)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:83)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65)
at android.support.test.internal.runner.junit4.AndroidJUnit4ClassRunner.<init>(AndroidJUnit4ClassRunner.java:38)
at android.support.test.runner.AndroidJUnit4.<init>(AndroidJUnit4.java:36)
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder.buildAndroidRunner(AndroidAnnotatedBuilder.java:57)
at android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder.runnerForClass(AndroidAnnotatedBuilder.java:45)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runner.Computer.getRunner(Computer.java:40)
at org.junit.runner.Computer$1.runnerForClass(Computer.java:31)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:101)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:87)
at org.junit.runners.Suite.<init>(Suite.java:81)
at org.junit.runner.Computer.getSuite(Computer.java:28)
at android.support.test.internal.runner.TestRequestBuilder.classes(TestRequestBuilder.java:701)
at android.support.test.internal.runner.TestRequestBuilder.build(TestRequestBuilder.java:664)
at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:329)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:226)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)

Caused by: java.lang.ClassNotFoundException: Didn't find class 
  "com.example.MainActivity" on path: DexPathList[[zip file 
  "/system/framework/android.test.runner.jar", zip file 
  "/data/app/com.example.debug.test-1.apk", zip file 
  "/data/app/com.example.debug-1.apk"],
  nativeLibraryDirectories=[/data/app-lib/com.example.debug.test-1, 
  /data/app-lib/com.example.debug-1, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
... 28 more

我基本上遵循espresso/BasicSample/ChangeTextBehaviorTest.java 中的结构。此测试在模拟器上有效

对于我的测试,当我只使用以下代码时,我可以归结为运行测试已经失败

@RunWith(AndroidJUnit4.class)
public class MainFragmentTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = 
        new ActivityTestRule<>(MainActivity.class);    
}

这是完整的测试类:

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;

import com.example.R;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;

@RunWith(AndroidJUnit4.class)
public class MainFragmentTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = 
        new ActivityTestRule<>(MainActivity.class);

    MainActivity mMainActivity;

    MainFragment mMainFragment;

    @Before
    public void setUp() {
        mMainActivity = mActivityRule.getActivity();
        mMainFragment = (MainFragment) mMainActivity
                .getSupportFragmentManager()
                .findFragmentByTag(MainFragment.FRAGMENT_TAG);
    }

    @Test
    public void testHeadline() {
        onView(withId(R.id.headline)).check(matches(withText(R.string.headline)));
    }
}

我目前正在使用以下工具链:

  • com.android.tools.build:gradle:1.4.0-beta2
  • buildToolsVersion "23.0.1"
  • 编译SdkVersion 22
  • targetSdkVersion 22
  • Gradle 包装器 2.5
  • java版本“1.7.0_79”OpenJDK

【问题讨论】:

    标签: android android-emulator android-testing android-espresso avd


    【解决方案1】:

    经过反复试验,我通过这个调整运行了我的:

    androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.1'
    

    改成

    androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2') {
        exclude group: 'com.android.support', module: 'support-v4'
    }
    

    不知何故,espresso-contrib 中包含一些内容,导致 support-v4 的正确版本无法包含在测试包中,并导致类加载器失败。

    【讨论】:

    • 谢谢,但我根本不包括espresso-contrib。尽管如此,我检查了espresso-core 是否依赖于support-v4;它没有。
    • @JJD 很难准确指出导致问题的库。使用解析策略并强制整个构建使用正确的库可能是最好的方法。见stackoverflow.com/a/29859202/133616
    • 感谢您的链接。我使用Gradle View plugin 来检查依赖树。
    • @JJD 不知道有这样的 IntelliJ 工具,感谢链接!!
    【解决方案2】:

    经过反复试验,我意识到 特定 AVD 模拟器会发生错误,而在其他模拟器上测试执行成功。我在问题中没有提到的一个重要的旁注是,我使用 运行测试的应用程序使用 Google Play 服务。因此,我需要选择提供框架的模拟器。

    测试成功运行于:

    • Android 6.0 (API 23) Google API 英特尔 x86 Atom 系统映像
    • Android 5.1.1 (API 22) Google API 英特尔 x86 Atom 系统映像

    测试失败:

    • Android 4.4.2 (API 19) Google API(x86 系统映像)

    未知/其他错误:

    • Android 5.1.1 (API 22) Google API 英特尔 x86 Atom_64 系统映像
      由于issue #180674 中描述的错误,我无法在此 AVD 上安装 APK。

    【讨论】:

      【解决方案3】:

      作为安装问题的解决方法,您还可以手动运行检测:

      1.生成目标和测试 apk

      gradle connectedAndroidTest
      

      安装 apk 会失败,但仍会生成它们作为输出。

      2。手动安装测试和目标 apk

      adb install XXX-debug-androidTest-unaligned.apk
      
      adb install XXX-debug.apk
      

      3.手动触发仪器

      adb shell am instrument -w -e your.package.test/.common.Instrumentation
      

      这将显示所有已安装的仪器:

      adb shell pm list instrumentation
      

      有关更多信息,请查看official instrumentation documentation

      【讨论】:

        猜你喜欢
        • 2016-01-11
        • 2016-04-29
        • 2016-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-03
        • 2011-03-22
        相关资源
        最近更新 更多