簡體   English   中英

如何使用 Espresso 測試片段

[英]How to test a Fragment using Espresso

我有一個要測試的 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;
    }
}

我將按照以下方式創建一個 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 線程中運行的代碼

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

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


}

如上所述,您可以從 UI 線程開始您的片段。

您可以使用FragmentTestRule

您必須使用而不是常規的ActivityTestRule

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

您可以在此博客文章中找到更多詳細信息

您可以使用androidx.fragment:fragment-testing庫。 在您的測試方法中啟動片段非常簡單:

val fragmentArgs = Bundle()
androidx.fragment.app.testing.launchFragmentInContainer<MyFragment>(fragmentArgs)

您可以在此處找到有關此庫的更多信息。

您可能忘記在視圖層次結構中注入片段。 嘗試定義保持件容器在你的片段TestActivity的布局(如FrameLayout id為fragment_container ),然后,而不是僅僅add(myFragment, "tag")使用add(R.id.fragment_container, myFragment, "tag")這個方法)。 我想您也可以使用具有相同簽名的replace方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM