2016-02-18 4 views
10

У меня есть фрагмент Android, который я хочу проверить. Я создал тестовую активность, к которой я добавляю этот фрагмент, и запускаю некоторые тесты эспрессо.Как проверить фрагмент с помощью Espresso

Однако Espresso не находит ни одного из видов внутри фрагмента. Он сбрасывает иерархию представлений, и все пусто.

Я не хочу использовать действительную родительскую активность. Я хочу просто проверить этот фрагмент изолированно. Кто-нибудь это сделал? Есть ли образец с похожим кодом?

@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

Вы пытались выполнить поиск в сети? Я нахожу много примеров. –

+0

Всегда полезно показать нам свой код. – Emzor

+1

Я попытался найти в сети. Я не смог найти примеров. @DougStevenson, я был бы признателен, если бы вы могли поделиться тем, что нашли. – greenrobo

ответ

0

Возможно, вы забыли вставить фрагмент в иерархию представлений. Попробуйте определить контейнер-держатель для вашего фрагмента в макете TestActivity (например, FrameLayout с идентификатором fragment_container), а затем вместо add(myFragment, "tag") используйте add(R.id.fragment_container, myFragment, "tag") (this method). Я думаю, вы могли бы использовать метод replace с той же подписью.

+0

Я пробовал этот метод (используя add (id, фрагмент, тег)), но это не помогло. Я подозреваю, что это связано с взаимодействием нескольких потоков. Эспрессо как-то не нравится. – greenrobo

4

я буду делать в следующий способ Создать ViewAction следующим образом:

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

Затем используйте ниже для запуска кода, который должен быть запущен в 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 
     } 
    })); 

ниже пример теста в случае добавления иерархии фрагментов

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


} 

Вы можете запустить свой фрагмент из потока пользовательского интерфейса, как указано выше.

0

Вы можете использовать FragmentTestRule.

Вместо обычной ActivityTestRule вы должны использовать:

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

Вы можете найти more details in this blog post.

Смежные вопросы