J'ai un fragment Android que je veux tester. J'ai créé une activité de test à laquelle j'ajoute ce fragment et exécute des tests d'espresso.
Cependant, Espresso ne trouve aucune des vues à l'intérieur du fragment. Il vide la hiérarchie de vues et tout est vide.
Je ne veux pas utiliser l'activité parent réelle. Je veux juste tester ce fragment de manière isolée. Quelqu'un a-t-il fait cela? Y at-il un échantillon qui a un code similaire?
@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;
}
}
Je ferai de la manière suivante Créer un ViewAction comme suit:
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();
}
};
}
Ensuite, utilisez ci-dessous pour lancer le code qui doit être exécuté dans UI Thread
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
}
}));
ci-dessous est un exemple de cas de test ajoutant la hiérarchie de vue fragmentée
@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));
}
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;
}
}
Vous pouvez commencer votre fragment à partir du fil d'interface utilisateur comme mentionné ci-dessus.
Vous avez probablement oublié d'injecter le fragment dans la hiérarchie des vues. Essayez de définir le conteneur de détenteur pour votre fragment dans la disposition TestActivity
(comme un FrameLayout
avec id fragment_container
), puis au lieu de add(myFragment, "tag")
, utilisez la fonction add(R.id.fragment_container, myFragment, "tag")
( this méthode ). Je suppose que vous pourriez également utiliser la méthode replace
avec la même signature.
Vous pouvez utiliser FragmentTestRule .
Au lieu de la ActivityTestRule
régulière, vous devez utiliser:
@Rule
public FragmentTestRule<?, FragmentWithoutActivityDependency> fragmentTestRule =
FragmentTestRule.create(FragmentWithoutActivityDependency.class);
Vous pouvez trouver plus de détails dans cet article de blog .