2016-02-18 18 views
10

Ho un frammento Android che voglio testare. Ho creato un'attività di test a cui aggiungo questo frammento ed eseguo alcuni test dell'Espresso.Come testare un frammento usando Espresso

Tuttavia, Espresso non trova nessuna vista all'interno del frammento. Scarica la gerarchia della vista ed è tutto vuoto.

Non voglio utilizzare l'attività padre effettiva. Voglio solo testare questo frammento da solo. Qualcuno ha fatto questo? C'è un campione che ha un codice simile?

@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; 
    } 
} 
+0

Hai provato a fare ricerche sul Web per questo? Trovo molti esempi –

+0

È sempre una buona idea mostrarci il tuo codice. – Emzor

+1

Ho provato a cercare in rete. Non sono stato in grado di trovare alcun esempio. @DougStevenson, sarei grato se potessi condividere ciò che hai trovato. – greenrobo

risposta

0

Probabilmente hai dimenticato di iniettare il frammento nella gerarchia della vista. Prova a definire il contenitore titolare per il frammento nel layout TestActivity (come un FrameLayout con ID fragment_container) e quindi anziché solo add(myFragment, "tag"), utilizza add(R.id.fragment_container, myFragment, "tag") (this method). Immagino che potresti usare il metodo replace con la stessa firma.

+0

Ho provato questo metodo (usando add (id, fragment, tag)) ma questo non ha aiutato. Sospetto che ciò sia dovuto all'interazione di più thread. L'espresso in qualche modo non gli piace. – greenrobo

4

Farò in modo seguente Crea una ViewAction come segue:

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

Quindi utilizzare qui sotto per avviare il codice che deve essere eseguito in UI Discussione

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

di seguito è un esempio di prova caso aggiungendo la gerarchia vista frammento

@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; 
    } 


} 

È possibile avviare il frammento dal thread dell'interfaccia utente come sopra indicato.

0

È possibile utilizzare FragmentTestRule.

Invece del normale ActivityTestRule è necessario utilizzare:

@Rule 
public FragmentTestRule<?, FragmentWithoutActivityDependency> fragmentTestRule = 
    FragmentTestRule.create(FragmentWithoutActivityDependency.class); 

Potete trovare more details in this blog post.

Problemi correlati