web-dev-qa-db-fra.com

Comment tester un fragment avec un expresso

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;
    }
}
12
greenrobo

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));

}
4
Ankur
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.

2
Siddharth Yadav

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.

0
karlicoss

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 .

0
Brais Gabin