我有一个活动可以显示不同的toast,具体取决于从Web服务调用返回的状态。
我正在编写一个测试类,我的第一个测试测试是在出现网络错误时显示其中一个toast。以下是测试类:
@RunWith(AndroidJUnit4.class)
public class LoginActivityTest extends BaseTest {
@Rule
public final ActivityTestRule<LoginActivity> login = new ActivityTestRule(LoginActivity.class, true);
@Test
public void noNetwork() {
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
login.getActivity().onEventMainThread(new LoginResp(CopiaWebServiceClient.ResponseStatus.NETWORK_ERROR));
}
});
onView(withText(R.string.toast_no_network_connection))
.inRoot(withDecorView(not(is(login.getActivity().getWindow().getDecorView()))))
.check(matches(isDisplayed()));
}
}
因此noNetwork
测试调用LoginActivity
&#39; onEventMainThread(LoginResp loginResp)
方法(这需要在UI线程上运行,因此我使用runOnMainSync
)网络错误状态,提示它显示预期的toast_no_network_connection toast。
此测试正常运行并成功通过。
这是我的问题:
如果我向测试类添加第二个测试,则第二个测试失败。这是第二次测试,完全相同,除了它将不同的错误状态传递给onEventMainThread(LoginResp loginResp)
,以便显示不同的吐司:
@Test
public void serverErr() {
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
login.getActivity().onEventMainThread(new LoginResp(CopiaWebServiceClient.ResponseStatus.HTTP_SERVER_ERROR));
}
});
onView(withText(R.string.toast_operation_failure_app_error))
.inRoot(withDecorView(not(is(login.getActivity().getWindow().getDecorView()))))
.check(matches(isDisplayed()));
}
第二次测试失败并输出:android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with string from resource id: <2131689669>[toast_operation_failure_app_error] value: Sorry, failure to complete operation due to application error.
但是,在运行测试时观察模拟器,我会看到初始toast_no_network_connection
吐司(第一次测试需要),然后是toast_operation_failure_app_error
吐司(第二次测试需要)。为什么第二次测试失败?
它与一个接一个地运行的测试有关,因为当我注释掉第一个测试时,第二个测试通过。
onEventMainThread(LoginResp loginResp)
中的LoginActivity
方法包含以下代码,根据状态显示适当的吐司:
switch (status) {
case HTTP_UNAUTHORIZED:
DialogCreator.createAlertDialog(this, getString(R.string.dialog_msg_login_fail)).show();
break;
case NETWORK_ERROR:
Toast.makeText(this, getString(R.string.toast_no_network_connection), Toast.LENGTH_SHORT).show();
break;
default:
Toast.makeText(this, getString(R.string.toast_operation_failure_app_error), Toast.LENGTH_SHORT).show();
}
调试测试我看到第一个测试按预期进入NETWORK_ERROR情况,第二个测试进入switch语句的default
部分,也正如预期的那样。
答案 0 :(得分:0)
在进一步玩测试之后,我选择了Eirik W在Espresso checking if toasts are displayed (one on top of another)
的回答中提出的方法我稍微改变了我的生产代码,将一个@VisibleForTesting(否则= VisibleForTesting.PRIVATE)注释Toast成员添加到LoginActivity,以便在LoginActivityTest中启用@After带注释的方法,在每次测试后取消任何显示的toast。