2016-02-18 22 views
10

Ich habe ein Android-Fragment, das ich testen möchte. Ich habe eine Testaktivität erstellt, zu der ich dieses Fragment hinzufüge und einige Espressotests durchführe.So testen Sie ein Fragment mit Espresso

Allerdings findet Espresso keine der Ansichten innerhalb des Fragments. Es speichert die Ansichtshierarchie und es ist alles leer.

Ich möchte nicht die tatsächliche übergeordnete Aktivität verwenden. Ich möchte dieses Fragment nur isoliert testen. Hat jemand das getan? Gibt es ein Beispiel mit einem ähnlichen Code?

@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

Haben Sie versucht, eine Internetsuche durchzuführen? Ich finde viele Beispiele. –

+0

Es ist immer eine gute Idee, uns Ihren Code zu zeigen. – Emzor

+1

Ich habe versucht, im Internet zu suchen. Ich konnte keine Beispiele finden. @DougStevenson, ich würde es begrüßen, wenn Sie teilen könnten, was Sie gefunden haben. – greenrobo

Antwort

0

Sie haben vergessen, wahrscheinlich das Fragment in der Ansichtshierarchie zu injizieren. Versuchen Sie, den Halterbehälter für Ihr Fragment im Layout TestActivity zu definieren (z. B. FrameLayout mit der ID fragment_container) und verwenden Sie dann anstelle von add(myFragment, "tag") die add(R.id.fragment_container, myFragment, "tag") (this method). Ich denke, Sie könnten die replace Methode mit der gleichen Signatur auch verwenden.

+0

Ich habe diese Methode (mit add (ID, Fragment, Tag)) versucht, aber das hat nicht geholfen. Ich vermute, dass dies aufgrund der Interaktion mehrerer Threads ist. Espresso mag das irgendwie nicht. – greenrobo

4

ich in folgender Weise tun eine Viewaction erstellen wie folgt:

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

Dann unten Code starten verwenden, die

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

unten in UI-Thread ausgeführt werden soll, die ein Beispiel für Test Fall, der Fragmentansichtshierarchie hinzufügt

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


} 

Sie können Ihr Fragment wie oben erwähnt über den UI-Thread starten.

0

Sie können FragmentTestRule verwenden.

Statt der regulären ActivityTestRule Sie verwenden müssen:

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

können Sie more details in this blog post finden.

Verwandte Themen