- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试整合 Espresso 2.0's AndoridJUnitRunner与 ActivityUnitTestCase。但是,当 startActivity() tries to initialize mMockParent = new MockParent() 时我的测试崩溃了.
这是我做的:
使用 Intellij 14 CE 创建一个新项目并对 build.gradle 进行一些更改。
android{
defaultConfig {
applicationId "com.noob.testing"
minSdkVersion 9
targetSdkVersion 21
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.+'
androidTestCompile('org.mockito:mockito-core:1.9.5')
androidTestCompile('com.google.dexmaker:dexmaker:1.2')
androidTestCompile('com.google.dexmaker:dexmaker-mockito:1.2')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.0')
androidTestCompile('com.android.support.test:testing-support-lib:0.1')
}
编写 JUnit4 风格的单元测试。
@RunWith(AndroidJUnit4.class)
public class MainActivityJUnit4Test extends ActivityUnitTestCase<MainActivity> {
public MainActivityJUnit4Test() {
super(MainActivity.class);
}
MainActivity activity;
@Before
public void setup() throws Exception {
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
super.setUp();
ContextThemeWrapper context = new ContextThemeWrapper(getInstrumentation().getTargetContext(), R.style.AppTheme);
setActivityContext(context);
activity = startActivity(new Intent(Intent.ACTION_MAIN), null, null);
}
@Test
public void baseCase() {
TextView tv = (TextView) activity.findViewById(R.id.tv);
Assert.assertEquals("Hello World", tv.getText());
}
}
运行测试,获取堆栈跟踪。
junit.framework.AssertionFailedError
at junit.framework.Assert.fail(Assert.java:48)
at junit.framework.Assert.assertTrue(Assert.java:20)
at junit.framework.Assert.assertNotNull(Assert.java:218)
at junit.framework.Assert.assertNotNull(Assert.java:211)
at android.test.ActivityUnitTestCase.startActivity(ActivityUnitTestCase.java:147)
at com.sdchang.testing.MainActivityJUnit4Test.setup(MainActivityJUnit4Test.java:32)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:270)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
这个堆栈跟踪实际上是对
的重新抛出java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
发生在 startActivity() tries to initialize mMockParent = new MockParent() 时:
ComponentName cn = new ComponentName(mActivityClass.getPackage().getName(),
mActivityClass.getName());
intent.setComponent(cn);
ActivityInfo info = new ActivityInfo();
CharSequence title = mActivityClass.getName();
mMockParent = new MockParent();
String id = null;
我是否遗漏了让 AndroidJUnitRunner 与 ActivityUnitTestCase 一起工作的其他任何东西?任何帮助将不胜感激。
最佳答案
在用头撞墙、 window 和各种家具后,我的测试终于成功了!
来自 a response on its issue tracker ,我了解到无法从检测线程创建新的处理程序。这意味着必须在 UI 线程中调用 startActivity()。这导致了 3 个解决方案。
1.使用 Instrumentation 的 runOnMainSync()
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
activity = startActivity(new Intent(Intent.ACTION_MAIN), null, null);
}
});
2.创建自己的基类,扩展 ActivityUnitTestCase 并覆盖 startActivity
@Override
protected T startActivity(final Intent intent, final Bundle savedInstanceState,
final Object lastNonConfigurationInstance) {
return startActivityOnMainThread(intent, savedInstanceState, lastNonConfigurationInstance);
}
private T startActivityOnMainThread(final Intent intent, final Bundle savedInstanceState,
final Object lastNonConfigurationInstance) {
final AtomicReference<T> activityRef = new AtomicReference<>();
final Runnable activityRunnable = new Runnable() {
@Override
public void run() {
activityRef.set(YourBaseActivityUnitTestCase.super.startActivity(
intent, savedInstanceState, lastNonConfigurationInstance));
}
};
if (Looper.myLooper() != Looper.getMainLooper()) {
getInstrumentation().runOnMainSync(activityRunnable);
} else {
activityRunnable.run();
}
return activityRef.get();
}
3.如果你在测试方法中调用startActivity()并且你的整个测试可以在主线程上运行,你可以简单地用@UiThreadTest注解你的测试方法。
在我的测试中,我尝试了所有 3 种解决方案,但只有 1 和 2 可行。
关于android - ActivityUnitTestCase 在使用 AndroidJUnitRunner 运行时抛出 RuntimeException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27991363/
我在我的项目中使用 AndroidJUnitRunner,但无论是在 Android Studio 中还是通过 gradlew 从命令行在设备和模拟器上执行单元测试都非常慢。 我正在使用这个开源项目的
只要指定类,我就可以运行仪器测试。 adb shell am instrument -w -e class com.application.instrumentation.BaseActivityTe
我使用 gradle 构建我的 android 应用程序。 我按照文档 ( https://developer.android.com/topic/libraries/testing-support-
设置: 我继承的一个较旧的项目有很多遗留的仪器测试,我想对它们施加超时,因为它们中的很多都可以无限期地挂起,这使得很难获得测试报告。我正在将测试更新为 Junit4 样式,但目前它们都在扩展 Acti
我有一个 Android 应用程序,我正在尝试使用 Jenkins 进行设置。我已经使用 Android 模拟器插件启动模拟器,并使用 gradle 脚本构建项目,但我无法让它运行我使用 Androi
我是 Android 测试领域的新手,单元测试示例提到了 AndroidJunit4 runner 的使用。我偶然发现了另一个名为 AndroidJUnitRunner 的运行者。现在,我看到了这两个
我正在尝试整合 Espresso 2.0's AndoridJUnitRunner与 ActivityUnitTestCase。但是,当 startActivity() tries to initia
在 Gradle 和 Run/Debug Configurations -> Android Tests -> MyInstrumentedTest -> General -> Specific in
我想使用 faSTLane screengrab,当我启动时 fastlane screengrab我有这个错误:android.util.AndroidException: INSTRUMENTAT
我们围绕相机功能进行了一些 UI 测试,在我们从 InstrumentationTestRunner 切换到 AndroidJUnitRunner 作为迁移到 Espresso/JUnit4 的一部分
我正在尝试使用插桩测试,并将我的项目更新为 AndroidX。但是在尝试运行时出现以下错误: 2018-10-09 14:22:29.468 13263-13263/xxx.yyy E/Android
我是仪器测试的新手。我正在尝试使用 AndroidJUnitRunner 进行基本测试。这是我的毕业典礼: apply plugin: 'com.android.application' androi
我正在尝试将我的项目更新为最近发布的 Android 测试支持库版本 1.0.0。但是,如果我添加 assertj-core 依赖项,Gradle 检测的测试任务开始失败,并显示“未找到测试”消息。不
我已经编写了一个简单的 Android 工具测试用例来测试网络操作。 Test case class name: Main3ActivityTest.java Method name:addNewEm
我尝试在 MultiDex 应用程序上运行 Espresso 测试,但失败并出现以下错误 Error:Execution failed for task > :transformClassesWith
几天以来,我一直在为我们的 MultiDex 应用程序中的 NoClassDefFoundError 和 AndroidJUnitRunner 而苦苦挣扎...... 因为我们想开始使用 Espres
我们将 Robotium 与 android.test.InstrumentationTestRunner 一起用于我们的测试。尽管如此,我们还是想用 Espresso 替换 Robotium,但我们
我在单元测试中使用了 robolectric。最近在我们的项目中,我们添加了一个来自 zendesk 的新依赖项。 repositories { maven { url 'ht
在我的应用程序上录制了一个简单的 Espresso 测试后,测试无法运行,我希望有人能指导我了解为什么会发生这种情况。产生的错误是: D/AndroidJUnitRunner: Use the raw
我是一名优秀的程序员,十分优秀!