ActivityScenario替代了Robolectric中的ActivityController和ATSL中的ActivityTestRule。
从ATSL重构到AndroidX测试时,我正在使用此代码在每次意式浓缩咖啡测试之前启动IndexActivity。
@Before
public void launchActivity() {
ActivityScenario<IndexActivity> scenario = ActivityScenario.launch(IndexActivity.class);
}
但是,我的测试在80-90%的时间内停滞不前并抛出此错误。
java.lang.AssertionError:活动永远不会变为请求状态“ [RESUMED]”(上一个生命周期过渡=“ STOPPED”)
尝试进行故障排除时,我将以上内容更改为:
@Before
public void launchActivity() {
ActivityScenario<IndexActivity> scenario = ActivityScenario.launch(IndexActivity.class);
scenario.moveToState(Lifecycle.State.RESUMED);
}
但是,我现在100%都遇到相同的错误。
根据文档,我不确定为什么会这样。
我正在使用AndroidX Test Orchestrator并在具有Api 28的仿真器上进行测试
要在此处进行测试的完整StackTrace:
10:54:42 V/InstrumentationResultParser: java.lang.AssertionError: Activity never becomes requested state "[RESUMED]" (last lifecycle transition = "STOPPED")
10:54:42 V/InstrumentationResultParser: at androidx.test.core.app.ActivityScenario.waitForActivityToBecomeAnyOf(ActivityScenario.java:228)
10:54:42 V/InstrumentationResultParser: at androidx.test.core.app.ActivityScenario.moveToState(ActivityScenario.java:368)
10:54:42 V/InstrumentationResultParser: at com.myapplication.android.test.HomeTest.launchActivity(HomeTest.java:30)
10:54:42 V/InstrumentationResultParser: at java.lang.reflect.Method.invoke(Native Method)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
10:54:42 V/InstrumentationResultParser: at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
10:54:42 V/InstrumentationResultParser: at androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:76)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
10:54:42 V/InstrumentationResultParser: at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:104)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.Suite.runChild(Suite.java:128)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.Suite.runChild(Suite.java:27)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
10:54:42 V/InstrumentationResultParser: at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
10:54:42 V/InstrumentationResultParser: at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
10:54:42 V/InstrumentationResultParser: at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
10:54:42 V/InstrumentationResultParser: at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
10:54:42 V/InstrumentationResultParser: at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:388)
10:54:42 V/InstrumentationResultParser: at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2075)
答案 0 :(得分:0)
声明:
ActivityScenario API的launch(Intent startActivityIntent)
方法内有一个限制。它会等待活动为Lifecycle.STATE.RESUMED
或DESTROYED
,如果不在4.5秒内,则会引发此错误。
上下文:
我的应用程序使用IndexActivity
加载配置,该配置指示应用程序进行某些API调用。但是,在加载DialogActivity
之后,IndexActivity
立即进入STOPPED
。接受DialogActivity
中的条款后,IndexActivity
回到RESUMED
,然后ActivityScenario可以正常工作。在我的测试中,Espresso是否可以在4.5秒内单击条款以使IndexActivity
成为RESUMED
还是在此之前会引发错误,这是一个竞争条件。要进行其他活动才能使用ActivityScenario启动,将需要进行大量的重构,因此这不是一个选择。
修复
在活动方案的public static <A extends Activity> ActivityScenario<A> launch(Intent startActivityIntent)
中,检查逻辑scenario.waitForActivityToBecomeAnyOf(State.RESUMED, State.DESTROYED);
如果您可以创建自己的自定义“活动方案”,并将此代码行调整为类似scenario.waitForActivityToBecomeAnyOf(State.STOPPED, State.DESTROYED);
,那么从理论上讲,它将对您有用。然后,您可以再次使用ActivityScenario将Activity移至所需的任何生命周期状态。
OR ,只需使用旧的https://developer.android.com/reference/androidx/test/rule/ActivityTestRule,直到Google在AndroidX Test中解决此问题为止。
TL; DR
发生这种情况是因为您的Activity的Lifecycle.State不是ActivityScenario.Launch()
等待RESUMED
或DESTROYED
这两个特定的生命周期状态之一。您的活动可能是在对话框的背景下,或者在创建API时没有想到的另一种极端情况下。
答案 1 :(得分:0)
为便于记录,此问题将在以后的版本中修复。 https://github.com/android/android-test/issues/143
答案 2 :(得分:0)
对我来说,这是因为我在关闭屏幕的情况下插入了设备并且正在运行模拟器。我以为我正在启动仿真器,但是我正在设备上运行它。由于屏幕关闭,因此测试永远无法转换为有效状态。