如果添加第二个测试,Espresso toast 测试将失败
Espresso toast test fails if second test is added
我有一个 activity 可以根据从网络服务调用返回的状态显示不同的 toast。
我正在编写一个测试 class,我的第一个测试测试在出现网络错误时会显示其中一个 toast。下面是测试 class:
@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
的 onEventMainThread(LoginResp loginResp)
方法(这需要 运行 在 UI 线程上,因此我使用 runOnMainSync
) 带有网络错误状态以提示它显示预期的 toast_no_network_connection toast。
此测试有效 运行 并成功通过。
这是我的问题:
如果我向测试 class 添加第二个测试,则第二个测试失败。这是第二个测试,与第一个相同,只是它向 onEventMainThread(LoginResp loginResp)
传递了不同的错误状态,因此将显示不同的 toast:
@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(第一个测试所期望的),然后是 toast_operation_failure_app_error
toast(第一个测试所期望的)第二次测试)。为什么第二次测试失败?
跟测试运行ning一个接一个有关系,因为我把第一个测试注释掉了,第二个测试通过了
我在 LoginActivity
中的 onEventMainThread(LoginResp loginResp)
方法具有以下代码,可根据状态显示适当的 Toast:
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
部分,也符合预期。
在进一步测试之后,我选择了 Eirik W 在
的回答中建议的方法
我稍微更改了生产代码,将 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) 注释的 Toast 成员添加到 LoginActivity 以启用 LoginActivityTest 中的 @After 注释方法取消每次测试后显示的任何 toast。
我有一个 activity 可以根据从网络服务调用返回的状态显示不同的 toast。
我正在编写一个测试 class,我的第一个测试测试在出现网络错误时会显示其中一个 toast。下面是测试 class:
@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
的 onEventMainThread(LoginResp loginResp)
方法(这需要 运行 在 UI 线程上,因此我使用 runOnMainSync
) 带有网络错误状态以提示它显示预期的 toast_no_network_connection toast。
此测试有效 运行 并成功通过。
这是我的问题:
如果我向测试 class 添加第二个测试,则第二个测试失败。这是第二个测试,与第一个相同,只是它向 onEventMainThread(LoginResp loginResp)
传递了不同的错误状态,因此将显示不同的 toast:
@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(第一个测试所期望的),然后是 toast_operation_failure_app_error
toast(第一个测试所期望的)第二次测试)。为什么第二次测试失败?
跟测试运行ning一个接一个有关系,因为我把第一个测试注释掉了,第二个测试通过了
我在 LoginActivity
中的 onEventMainThread(LoginResp loginResp)
方法具有以下代码,可根据状态显示适当的 Toast:
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
部分,也符合预期。
在进一步测试之后,我选择了 Eirik W 在
我稍微更改了生产代码,将 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) 注释的 Toast 成员添加到 LoginActivity 以启用 LoginActivityTest 中的 @After 注释方法取消每次测试后显示的任何 toast。