【发布时间】:2016-06-17 12:50:17
【问题描述】:
几天以来,我一直在为我们的 MultiDex-Application 中的 NoClassDefFoundError 和 AndroidJUnitRunner 苦苦挣扎......
因为我们想开始使用 Espresso 进行 Click-Tests,我们将 TestRunner 从“MultiDexTestRunner”更改为“AndroidJUnitRunner”。通过此更改,我们在 API 19 下的设备遇到了一些问题。当我们执行 @SmallTests 时,我们收到“未执行测试”导致 NoClassDefFoundError 的响应
在我们的 Logcat 中,我们得到以下信息:
06-17 14:19:13.832 26531-26779/com.xxxxxx.debug E/AndroidRuntime: FATAL EXCEPTION: Instr: com.xxxxxxxx.test.WakefulTestRunner
java.lang.ExceptionInInitializerError
at android.support.test.internal.runner.TestRequestBuilder.addFromRunnerArgs(TestRequestBuilder.java:713)
at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:350)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:260)
at com.xxxxxxxxxx.test.WakefulTestRunner.onStart(WakefulTestRunner.java:54)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1619)
Caused by: java.lang.NoClassDefFoundError: java.util.Objects
at android.support.test.internal.runner.TestSize.hashCode(TestSize.java:212)
at java.util.HashMap.put(HashMap.java:390)
at java.util.HashSet.add(HashSet.java:95)
at java.util.HashSet.<init>(HashSet.java:77)
at android.support.test.internal.runner.TestSize.<clinit>(TestSize.java:65)
at android.support.test.internal.runner.TestRequestBuilder.addFromRunnerArgs(TestRequestBuilder.java:713)
at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:350)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:260)
at com.xxxxxxxx.test.WakefulTestRunner.onStart(WakefulTestRunner.java:54)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1619)
这是 WakefulTestRunner 所需的部分:
public class WakefulTestRunner extends AndroidJUnitRunner {
private PowerManager.WakeLock wakeLock;
private KeyguardManager.KeyguardLock keyguardLock;
@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle arguments) {
MultiDex.install(getTargetContext());
super.onCreate(arguments);
String simpleName = WakefulTestRunner.class.getSimpleName();
// Unlock the device so that the tests can input keystrokes.
keyguardLock = ((KeyguardManager) getContext().getSystemService(KEYGUARD_SERVICE)).newKeyguardLock(simpleName);
// Wake up the screen.
int levelAndFlags = android.os.PowerManager.FULL_WAKE_LOCK
| android.os.PowerManager.ACQUIRE_CAUSES_WAKEUP
| android.os.PowerManager.ON_AFTER_RELEASE;
wakeLock = ((PowerManager) getContext().getSystemService(POWER_SERVICE)).newWakeLock(levelAndFlags, simpleName);
}
@Override
public void onStart() {
runOnMainSync(new Runnable() {
@Override
public void run() {
keyguardLock.disableKeyguard();
wakeLock.acquire();
}
});
super.onStart();
}
我们还在 build.gradle 中排除了很多不同的东西,但没有任何帮助:
configurations {
// This dependency set is for annotation processors.
// They're added below directly to the java compiler.
apt
androidTestCompile.exclude group: 'com.android.support', module: 'support-v4'
androidTestCompile.exclude group: 'com.android.support', module: 'recyclerview-v7'
androidTestCompile.exclude group: 'com.android.support', module: 'support-v13'
androidTestCompile.exclude group: 'com.android.support', module: 'appcompat-v7'
androidTestCompile.exclude group: 'com.android.support', module: 'cardview-v7'
}
defaultConfig {
minSdkVersion 15
targetSdkVersion 23
versionCode versionMajor * 10000 + versionMinor * 100 + versionMicro
versionName "${versionMajor}.${versionMinor}.${versionMicro}"
multiDexEnabled true
//intended to fix install issue -505 (https://code.google.com/p/android/issues/detail?id=189079)
applicationId = "com.xxxxxxxx"
testInstrumentationRunner "com.xxxxxxxxx.test.WakefulTestRunner"
}
【问题讨论】:
-
对象是在 api 级别 19 中引入的 - 可能是问题...
-
这听起来是一个很好的理由,但你知道如何解决它或为此创建一个解决方法吗?自从我们更改为“AndroidJUnitRunner”后,我们遇到了这个问题。
-
谢谢,但正如您在 logcat 中看到的那样,问题不是出现在我们的代码中,而是出现在 'android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java: 260)'
-
您不能使用 API 19 中引入的 API,然后在较低的 API 级别使用它们。
标签: java android unit-testing testing android-espresso