编辑:更新了说明和错误消息并添加了一些图像。还是有这个问题。
运行espresso测试时,我发生了多次奇怪的错误。在几次成功的测试运行之后,测试开始失败并出现以下异常:
06-23 13:04:48.438 info TestRunner failed: WhenNavigatingToReportsThenCorrectViewShouldBeShown(com.myapp.ui.views.MainActivityTest)
06-23 13:04:48.439 info TestRunner ----- begin exception -----
06-23 13:04:48.441 info TestRunner android.support.test.espresso.NoActivityResumedException: No activities in stage RESUMED. Did you forget to launch the activity. (test.getActivity() or similar)?
06-23 13:04:48.441 info TestRunner at dalvik.system.VMStack.getThreadStackTrace(Native Method)
06-23 13:04:48.441 info TestRunner at java.lang.Thread.getStackTrace(Thread.java:580)
06-23 13:04:48.441 info TestRunner at android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:82)
06-23 13:04:48.441 info TestRunner at android.support.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:53)
06-23 13:04:48.441 info TestRunner at android.support.test.espresso.ViewInteraction.runSynchronouslyOnUiThread(ViewInteraction.java:184)
06-23 13:04:48.441 info TestRunner at android.support.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:115)
06-23 13:04:48.441 info TestRunner at android.support.test.espresso.ViewInteraction.perform(ViewInteraction.java:87)
06-23 13:04:48.441 info TestRunner at com.myapp.ui.views.MainActivityTest.WhenNavigatingToReportsThenCorrectViewShouldBeShown(MainActivityTest.java:96)
06-23 13:04:48.441 info TestRunner at java.lang.reflect.Method.invoke(Native Method)
06-23 13:04:48.441 info TestRunner at java.lang.reflect.Method.invoke(Method.java:372)
06-23 13:04:48.441 info TestRunner at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
06-23 13:04:48.441 info TestRunner at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
06-23 13:04:48.441 info TestRunner at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
06-23 13:04:48.441 info TestRunner at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
06-23 13:04:48.441 info TestRunner at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
06-23 13:04:48.441 info TestRunner at android.support.test.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55)
06-23 13:04:48.441 info TestRunner at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:257)
06-23 13:04:48.441 info TestRunner at org.junit.rules.RunRules.evaluate(RunRules.java:18)
06-23 13:04:48.441 info TestRunner at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
06-23 13:04:48.441 info TestRunner at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
06-23 13:04:48.441 info TestRunner at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
06-23 13:04:48.441 info TestRunner at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
06-23 13:04:48.441 info TestRunner at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
06-23 13:04:48.441 info TestRunner at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
06-23 13:04:48.441 info TestRunner at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
06-23 13:04:48.441 info TestRunner at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
06-23 13:04:48.441 info TestRunner at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
06-23 13:04:48.441 info TestRunner at org.junit.runners.Suite.runChild(Suite.java:128)
06-23 13:04:48.441 info TestRunner at org.junit.runners.Suite.runChild(Suite.java:24)
06-23 13:04:48.441 info TestRunner at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
06-23 13:04:48.441 info TestRunner at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
06-23 13:04:48.441 info TestRunner at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
06-23 13:04:48.441 info TestRunner at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
06-23 13:04:48.441 info TestRunner at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
06-23 13:04:48.441 info TestRunner at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
06-23 13:04:48.441 info TestRunner at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
06-23 13:04:48.441 info TestRunner at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
06-23 13:04:48.441 info TestRunner at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:54)
06-23 13:04:48.441 info TestRunner at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:228)
06-23 13:04:48.441 info TestRunner at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1837)
06-23 13:04:48.441 info TestRunner ----- end exception -----
06-23 13:04:48.443 info TestRunner finished: WhenNavigatingToReportsThenCorrectViewShouldBeShown(com.myapp.ui.views.MainActivityTest)
我有一个简单的应用程序,导航到此时只包含文本的页面,测试应导航到每个页面并识别此文本。
@RunWith(AndroidJUnit4.class)
@LargeTest
public class MainActivityTest {
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule(MainActivity.class);
private MainActivity mainActivity;
@Before
public void setActivity() {
mainActivity = mActivityRule.getActivity();
}
@Test
public void WhenNavigatingToReportsThenCorrectViewShouldBeShown() {
onView(allOf(withId(R.id.icon), hasSibling(withText(R.string.reports)))).perform(click());
onView(withText("This is the Reports Activity.")).check(matches(isDisplayed()));
Spoon.screenshot(mainActivity, "main_view");
}
}
此故障仅发生在真实设备上。在模拟设备上,测试工作正常。见下图。
所有测试都是由gradle脚本执行的,从删除之前的应用程序和测试api开始,然后重新安装。确保环境清洁。日志表明卸载成功。然后部署新应用程序并开始运行测试。现在他们失败了。
如果测试失败,直到我手动从设备中删除应用程序和测试api,我才能再次成功进行测试。但只有一段时间,直到出现相同的错误。
为什么我会得到NoActivityResumedException,我找不到它是什么以及何时发生的好例子。
答案 0 :(得分:74)
我遇到了同样的问题。当设备上的屏幕关闭时会发生这种情况。打开屏幕应该可以解决问题。
答案 1 :(得分:8)
您可以在每次测试前使用Uiautomator唤醒设备。
@Before
public void init(){
UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
Point[] coordinates = new Point[4];
coordinates[0] = new Point(248, 1520);
coordinates[1] = new Point(248, 929);
coordinates[2] = new Point(796, 1520);
coordinates[3] = new Point(796, 929);
try {
if (!uiDevice.isScreenOn()) {
uiDevice.wakeUp();
uiDevice.swipe(coordinates, 10);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
答案 2 :(得分:1)
主要是因为如果您的连接未处于活动模式,则该连接也不应处于睡眠模式,而必须在已编写测试用例的应用程序中进行。 假设您已经使用了@Rule Activity启动规则。
答案 3 :(得分:0)
为避免这种情况,请让您的设备保持清醒状态。设备的开发人员选项中有一个选项。
您可以使用com.android.ddmlib和gradle任务通过adb为每次构建运行和您正在测试的每台设备更改设备设置。
import com.android.ddmlib.AndroidDebugBridge
import com.android.ddmlib.CollectingOutputReceiver
import com.android.ddmlib.IDevice
import com.android.ddmlib.NullOutputReceiver
task stayAwake {
description = "Activate the Stay Awake settings in the developer options."
group = "Device Setup"
AndroidDebugBridge.initIfNeeded(false)
def bridge = AndroidDebugBridge.createBridge(android.adbExecutable.path, false)
doLast {
bridge.devices.each {
it.executeShellCommand("settings put global stay_on_while_plugged_in 3", NullOutputReceiver.receiver)
println "Device ${it} will stay awake."
}
}
}
此外,您可以使用其他gradle任务激活屏幕。 (前提条件是没有设置PIN或解锁图案)
IDevice.metaClass.inputKeyEventByShell {
delegate.executeShellCommand("input keyevent ${it}", NullOutputReceiver.receiver)
}
IDevice.metaClass.inputSwipeByShell {
delegate.executeShellCommand("input swipe ${it}", NullOutputReceiver.receiver)
}
task unlockScreen {
description = "Activate screen and unlock device."
group = "Device Setup"
AndroidDebugBridge.initIfNeeded(false)
def bridge = AndroidDebugBridge.createBridge(android.adbExecutable.path, false)
doLast {
bridge.devices.each {
def receiver = CollectingOutputReceiver.newInstance()
it.executeShellCommand("dumpsys power | grep \"mHolding\"", receiver)
def displaySuspendFalse = receiver.getOutput().find("mHoldingDisplaySuspendBlocker=false")
def wakelockSuspendFalse = receiver.getOutput().find("mHoldingWakeLockSuspendBlocker")
if (displaySuspendFalse || wakelockSuspendFalse) {
it.inputKeyEventByShell('26') //power keyevent
println "Screen of device $it activated & unlocked."
}
it.inputSwipeByShell('100 500 100 1450 100') //swipe action
}
}
}
让这些任务在负责UI测试的gradle任务之前运行。
这样,您的测试中不需要额外的代码来激活设备并使其保持活动状态。
答案 4 :(得分:0)
一个可能的原因是测试并行运行。使用--no-parallel
。
示例-> gradlew connectedLiveDebugAndroidTest --no-parallel
仅当从控制台或按顺序运行它们时才会发生这种情况,但不会单独运行它们,而是有可能它们在同一设备上并行运行。同时在同一设备上运行的两种不同的Espresso测试使它们易碎且容易失败。
答案 5 :(得分:0)
在我的情况下,解决方案是使用UI Automater
val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
uiDevice.findObject(UiSelector().textContains("text")).click()
我想点击由Google登录SDK托管的活动。我注意到即使被测试应用程序的进程被杀死,SDK触发的活动仍然可见。因此,我使用UI Automator来进行跨应用程序功能UI测试