在 (Espresso) Android 仪器测试中启动特定导体控制器
Start specific conductor controller in (Espresso) Android instrumentation test
我正在为使用 Conductor. I'd like to specify which controller to start for each test, so that I don't need to get Espresso to click through the app from the beginning Activity for each. Since there is only one Activity and not much on SO or google about Conductor the closest I could find was 问题编写的应用编写 Espresso 测试?或者这是不可能的?
我试过使路由器静态并添加 getter 以尝试设置特定的根以进行测试但没有成功。
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
在 MainActivity 中:
public static Router getRouter() {
return router;
}
在仪器测试中:
@Rule
public ActivityTestRule<MainActivity> testRule = new ActivityTestRule<>(MainActivity.class);
@Before
public void setUp() {
Router router = testRule.getActivity().getRouter();
router.setRoot(RouterTransaction.with(new ControllerIwantToTest()));
}
@Test
public void titleIsDisplayed() {
onView(withText("My Controllers Title")).check(matches(isDisplayed()));
}
如果其他人遇到同样的问题,我已经通过执行以下操作解决了问题:
@RunWith(AndroidJUnit4.class)
public class NoBundleControllerEspressoTest {
private Router router;
@Rule
public ActivityTestRule<NoBundleConductorActivity> testRule = new ActivityTestRule<>(NoBundleConductorActivity.class);
@Before
public void setUp() {
Activity activity = testRule.getActivity();
activity.runOnUiThread(() -> {
router = testRule.getActivity().getRouter();
router.setRoot(RouterTransaction.with(new NoBundleController()));
});
}
@Test
public void titleIsDisplayed() {
onView(withText("Super Awesome Title")).check(matches(isDisplayed()));
}
}
或者,如果您的控制器像我们大多数人一样在其构造函数中使用 Bundle
:
@RunWith(AndroidJUnit4.class)
public class BundleControllerEspressoTest {
private Router router;
private ControllerBundleData controllerData;
@Rule
public ActivityTestRule<BundleConductorActivity> testRule = new ActivityTestRule<>(BundleConductorActivity.class);
@Before
public void setUp() {
controllerData = new ControllerBundleData();
Bundle bundle = new Bundle();
bundle.putSerializable(YOUR_BUNDLE_KEY, controllerData);
Activity activity = testRule.getActivity();
activity.runOnUiThread(() -> {
router = testRule.getActivity().getRouter();
router.setRoot(RouterTransaction.with(new BundleController(bundle)));
});
}
@Test
public void titleIsDisplayed() {
onView(withText("Super Awesome Title")).check(matches(isDisplayed()));
}
}
我正在为使用 Conductor. I'd like to specify which controller to start for each test, so that I don't need to get Espresso to click through the app from the beginning Activity for each. Since there is only one Activity and not much on SO or google about Conductor the closest I could find was
我试过使路由器静态并添加 getter 以尝试设置特定的根以进行测试但没有成功。
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
在 MainActivity 中:
public static Router getRouter() {
return router;
}
在仪器测试中:
@Rule
public ActivityTestRule<MainActivity> testRule = new ActivityTestRule<>(MainActivity.class);
@Before
public void setUp() {
Router router = testRule.getActivity().getRouter();
router.setRoot(RouterTransaction.with(new ControllerIwantToTest()));
}
@Test
public void titleIsDisplayed() {
onView(withText("My Controllers Title")).check(matches(isDisplayed()));
}
如果其他人遇到同样的问题,我已经通过执行以下操作解决了问题:
@RunWith(AndroidJUnit4.class)
public class NoBundleControllerEspressoTest {
private Router router;
@Rule
public ActivityTestRule<NoBundleConductorActivity> testRule = new ActivityTestRule<>(NoBundleConductorActivity.class);
@Before
public void setUp() {
Activity activity = testRule.getActivity();
activity.runOnUiThread(() -> {
router = testRule.getActivity().getRouter();
router.setRoot(RouterTransaction.with(new NoBundleController()));
});
}
@Test
public void titleIsDisplayed() {
onView(withText("Super Awesome Title")).check(matches(isDisplayed()));
}
}
或者,如果您的控制器像我们大多数人一样在其构造函数中使用 Bundle
:
@RunWith(AndroidJUnit4.class)
public class BundleControllerEspressoTest {
private Router router;
private ControllerBundleData controllerData;
@Rule
public ActivityTestRule<BundleConductorActivity> testRule = new ActivityTestRule<>(BundleConductorActivity.class);
@Before
public void setUp() {
controllerData = new ControllerBundleData();
Bundle bundle = new Bundle();
bundle.putSerializable(YOUR_BUNDLE_KEY, controllerData);
Activity activity = testRule.getActivity();
activity.runOnUiThread(() -> {
router = testRule.getActivity().getRouter();
router.setRoot(RouterTransaction.with(new BundleController(bundle)));
});
}
@Test
public void titleIsDisplayed() {
onView(withText("Super Awesome Title")).check(matches(isDisplayed()));
}
}