2016-02-18 15 views
10

Mam fragment Androida, który chcę przetestować. Stworzyłem testową akcję, do której dodałem ten fragment i uruchomiłem kilka testów Espresso.Jak testować fragment za pomocą Espresso

Jednak Espresso nie znajduje żadnego z widoków wewnątrz fragmentu. Zrzuca hierarchię widoków i jest pusty.

Nie chcę używać rzeczywistej aktywności rodzica. Chcę tylko przetestować ten fragment w izolacji. Czy ktoś to zrobił? Czy istnieje próbka, która ma podobny kod?

@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

Czy próbowałeś wyszukiwać w Internecie? Znajduję wiele przykładów. –

+0

Zawsze dobrze jest pokazać nam swój kod. – Emzor

+1

Próbowałem szukać w sieci. Nie znalazłem żadnych przykładów. @DougStevenson, byłbym wdzięczny, gdybyś mógł podzielić się tym, co znalazłeś. – greenrobo

Odpowiedz

0

Prawdopodobnie zapomniałeś wstawić fragment w hierarchii widoku. Spróbuj zdefiniować kontener dla swojego fragmentu w układzie TestActivity (jak FrameLayout o identyfikatorze fragment_container), a następnie zamiast tylko add(myFragment, "tag"), użyj add(R.id.fragment_container, myFragment, "tag") (this method). Sądzę, że możesz użyć metody replace z tą samą sygnaturą.

+0

Próbowałem tej metody (przy użyciu add (identyfikator, fragment, tag)), ale to nie pomogło. Podejrzewam, że dzieje się tak z powodu interakcji wielu wątków. Espresso jakoś tego nie lubi. – greenrobo

4

zrobię w następujący sposób Tworzenie ViewAction następująco:

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

Następnie użyj poniżej, aby uruchomić kod, który powinien być prowadzony w UI wątek

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

poniżej jest przykładem testu dodawanie przypadku hierarchii widoku fragmentów

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


} 

Możesz uruchomić swój fragment z wątku UI, jak wspomniano powyżej.

0

Można użyć FragmentTestRule.

Zamiast zwykłego ActivityTestRule trzeba wykorzystać:

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

można znaleźć more details in this blog post.

Powiązane problemy