Как проверить фрагмент с помощью эспрессо
У меня есть фрагмент Android, который я хочу протестировать. Я создал тестовую активность, к которой я добавляю этот фрагмент, и запускаю некоторые тесты эспрессо.
Однако Espresso не находит ни одного из видов внутри фрагмента. Он сбрасывает иерархию представления, и все пусто.
Я не хочу использовать действительную родительскую активность. Я хочу просто проверить этот фрагмент изолированно.
Кто-нибудь сделал это? Есть ли образец с похожим кодом?
@RunWith(AndroidJUnit4.class)
class MyFragmentTest {
@Rule
public ActivityTestRule activityRule = new ActivityTestRule<>(
TestActivity.class);
@Test
public void testView() {
MyFragment myFragment = startMyFragment();
myFragment.onEvent(new MyEvent());
// MyFragment has a recyclerview.
//OnEvent is EventBus callback that in this test contains no data.
//I want the fragment to display empty list text and hide the recyclerView
onView(withId(R.id.my_empty_text)).check(matches(isDisplayed()));
onView(withId(R.id.my_recycler)).check(doesNotExist()));
}
private MyFragment startMyFragment() {
FragmentActivity activity = (FragmentActivity) activityRule.getActivity();
FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
MyFragment myFragment = new MyFragment();
transaction.add(myFragment, "myfrag");
transaction.commit();
return myFragment;
}
}
Ответы
Ответ 1
Я буду делать следующим образом
Создайте ViewAction следующим образом:
public static ViewAction doTaskInUIThread(final Runnable r) {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isRoot();
}
@Override
public String getDescription() {
return null;
}
@Override
public void perform(UiController uiController, View view) {
r.run();
}
};
}
Затем используйте ниже, чтобы запустить код, который должен быть запущен в потоке пользовательского интерфейса
onView(isRoot()).perform(doTaskInUIThread(new Runnable() {
@Override
public void run() {
//Code to add your fragment or anytask that you want to do from UI Thread
}
}));
ниже приведен пример тестового примера добавления иерархии представлений фрагментов
@Test
public void testSelectionOfTagsAndOpenOtherPage() throws Exception{
Runnable r = new Runnable() {
@Override
public void run() {
//Task that need to be done in UI Thread (below I am adding a fragment)
}
};
onView(isRoot()).perform(doTaskInUIThread(r));
}
Ответ 2
public class VoiceFullScreenTest {
@Rule
public ActivityTestRule activityRule = new ActivityTestRule<>(
TestActivity.class);
@Test
public void fragment_can_be_instantiated() {
activityRule.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
VoiceFragment voiceFragment = startVoiceFragment();
}
});
// Then use Espresso to test the Fragment
onView(withId(R.id.iv_record_image)).check(matches(isDisplayed()));
}
private VoiceFragment startVoiceFragment() {
TestActivity activity = (TestActivity) activityRule.getActivity();
FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
VoiceFragment voiceFragment = new VoiceFragment();
transaction.add(voiceFragment, "voiceFragment");
transaction.commit();
return voiceFragment;
}
}
Вы можете запустить свой фрагмент из потока пользовательского интерфейса, как указано выше.
Ответ 3
Вероятно, вы забыли вставить фрагмент в иерархию представлений. Попробуйте определить контейнер-держатель для вашего фрагмента в макете TestActivity
(например, FrameLayout
с id fragment_container
), а затем вместо просто add(myFragment, "tag")
используйте add(R.id.fragment_container, myFragment, "tag")
(этот метод). Я думаю, вы могли бы использовать метод replace
с той же сигнатурой.
Ответ 4
Вы можете использовать FragmentTestRule.
Вместо обычного ActivityTestRule
вы должны использовать:
@Rule
public FragmentTestRule<?, FragmentWithoutActivityDependency> fragmentTestRule =
FragmentTestRule.create(FragmentWithoutActivityDependency.class);
Вы можете найти более подробную информацию в этом сообщении в блоге.
Ответ 5
Если вы в порядке, используя альфа-версии библиотек androidx, тогда вы можете использовать androidx.fragment:fragment-testing
библиотеку для androidx.fragment:fragment-testing
. На момент написания статьи последняя версия 1.1.0-alpha07
.
Запуск фрагмента в вашем тестовом методе так же прост, как:
val fragmentArgs = Bundle()
androidx.fragment.app.testing.launchFragmentInContainer<MyFragment>(fragmentArgs)
Вы можете найти больше информации об этой библиотеке здесь.