Java Android工具测试-UI线程问题
我正在尝试为我的Android应用程序编写一个仪器测试 我遇到了一些奇怪的线程问题,似乎找不到解决方案 我的原始测试:Java Android工具测试-UI线程问题,java,android,multithreading,testing,junit,Java,Android,Multithreading,Testing,Junit,我正在尝试为我的Android应用程序编写一个仪器测试 我遇到了一些奇怪的线程问题,似乎找不到解决方案 我的原始测试: @RunWith(AndroidJUnit4.class) public class WorkOrderDetailsTest { @Rule public ActivityTestRule<WorkOrderDetails> activityRule = new ActivityTestRule<>(WorkOrderDetails.
@RunWith(AndroidJUnit4.class)
public class WorkOrderDetailsTest {
@Rule
public ActivityTestRule<WorkOrderDetails> activityRule = new ActivityTestRule<>(WorkOrderDetails.class);
@Test
public void loadWorkOrder_displaysCorrectly() throws Exception {
final WorkOrderDetails activity = activityRule.getActivity();
WorkOrder workOrder = new WorkOrder();
activity.updateDetails(workOrder);
//Verify customer info is displayed
onView(withId(R.id.customer_name))
.check(matches(withText("John Smith")));
}
}
@RunWith(AndroidJUnit4.class)
public class WorkOrderDetailsTest {
//Note: This is new
@Rule
public UiThreadTestRule uiThreadTestRule = new UiThreadTestRule();
@Rule
public ActivityTestRule<WorkOrderDetails> activityRule = new ActivityTestRule<>(WorkOrderDetails.class);
@Test
@UiThreadTest //Note: This is new
public void loadWorkOrder_displaysCorrectly() throws Exception {
final WorkOrderDetails activity = activityRule.getActivity();
WorkOrder workOrder = new WorkOrder();
activity.updateDetails(workOrder);
//Verify customer info is displayed
onView(withId(R.id.customer_name))
.check(matches(withText("John Smith")));
}
}
java.lang.IllegalStateException:无法在主应用程序线程(on:main)上调用方法
(注意:此堆栈跟踪中的所有方法都不是我的代码)
它似乎给了我复杂的结果。。。如果它需要在创建视图的原始线程上运行,但不能在主线程上运行,那么它应该在哪个线程上运行
我非常感谢任何帮助或建议 这些检测测试在自己的应用程序中运行。这也意味着,它们在自己的线程中运行 您必须将您的工具视为与实际应用程序一起安装的东西,因此您可能的交互是“有限的” 您需要从应用程序的UIThread/主线程调用所有视图方法,因此调用
activity.updateDetails(workOrder)检测线程中的代码>不是应用程序主线程。这就是引发异常的原因
您只需在主线程上运行需要测试的代码,就像您在应用程序中使用
activity.runOnUiThread(new Runnable() {
public void run() {
activity.updateDetails(workOrder);
}
}
这样,您的测试就可以运行了
您收到的非法状态异常似乎是由于您与规则的交互。美国
请注意,当存在此注释时,可能不会使用检测方法
如果您在
之前在@中启动/获取活动,它也应该可以工作。您可以在以下帮助下在主UI线程上运行部分测试:
在大多数情况下,使用UiThreadTest
注释测试方法更简单,但是,它可能会导致其他错误,例如java.lang.IllegalStateException:无法在主应用程序线程(on:main)
上调用方法
FYR,这里引用的是的Javadoc:
注意,由于当前JUnit的限制,在UI线程上也会执行在之前和之后加上注释的方法如果这是一个问题,请考虑使用rununuithread(Runnable)。
请注意上面提到的UiThreadTest
(packageandroid.support.test.annotation
)不同于((packageandroid.test
)。公认的答案完美地描述了正在发生的事情
另外,如果有人想知道为什么Espresso的触动用户界面的方法,例如perform(ViewActions…
)不需要这样做,那只是因为他们后来为我们做了
如果您遵循perform(ViewActions…
,您会发现它最终会执行以下操作(在android.support.test.espresso.ViewInteraction
):
mainThreadExecutor
本身用@MainThread
注释
换句话说,意式浓缩咖啡也需要遵循David在公认答案中描述的相同规则。公认答案现在已被弃用
实现这一点的最简单方法是使用UiThreadTest
import android.support.test.annotation.UiThreadTest;
@Test
@UiThreadTest
public void myTest() {
// Set up conditions for test
// Call the tested method
activity.doSomethingWithAView()
// Verify that the results are correct
}
在androidx测试运行程序中,添加了一个新类UiThreadStatement
,该类提供了一个runOnUiThread
方法
UiThreadStatement.runOnUiThread {
// call activity here
}
当与getInstrumentation().waitForIdleSync()结合使用时,runOnUiThread
方法起作用代码>。不幸的是,之前的@方法没有起作用。谢谢你的帮助当您在之后立即有一个断言时,这一点很重要,否则您可能会得到一个测试结果不一致的竞争条件!如果未来的访问者偶然发现Android.Test.UIThreadTest在API 24:Android 7.0(Nougat)
之后被弃用,请注意这不是相同的注释。此答案使用支持注释。虽然为我做过牛轧糖myTest
这项活动,但我无法解决这个问题?这就是我一直坚持的。
import android.support.test.annotation.UiThreadTest;
@Test
@UiThreadTest
public void myTest() {
// Set up conditions for test
// Call the tested method
activity.doSomethingWithAView()
// Verify that the results are correct
}
UiThreadStatement.runOnUiThread {
// call activity here
}