Tiago Tiago -3 years ago 106
Android Question

Android - Independent Fragment UI testing tool

I've been looking for a way to test the UI of my Fragments separately (ie, independently from other fragments and activities) but I can't find a way to do it.

In particular, let's say I have Fragment A, Fragment B and Fragment C. The only way (app-wise) to go to Fragment C is by passing through Fragment A and Fragment B first. I am looking for a way to test Fragment C directly (potentially by mocking its dependencies, if any exists), without having to pass through Fragment A and B.

Tools I investigated so far:

  • monkey: only used to generate pseudo-random events through command line. Not what I want.

  • monkeyrunner: it can run Python programs to send event streams to my Android app, but it cannot target a particular Fragment directly with those scripts.

  • Espresso: white-box testing tool. This comes close to what I want, but it still requires passing through Fragment A and B before reaching Fragment C (ie, you need to start your app and then the tests will run from there).

  • UI Automator: black-box testing tool. This also comes close, but again, it requires passing through the previous Fragments before testing the one I want (Fragment C).

Is there any way to test the UI of a Fragment directly?

Answer Source

I'm am using a custom FragmentTestRule and Espresso to test each of my Fragments in isolation.

I have a dedicated TestActivity that shows the tested Fragments in my app. In my case the Activity only exists in the debug variant because my instrumentation tests run against debug.

1. Create a TestActivity in src/debug/java/your/package/TestActivity.java with a content view where the tested Fragment will be added to:

public class TestActivity extends AppCompatActivity {
    protected void onCreate(@Nullable final Bundle savedInstanceState) {
        FrameLayout frameLayout = new FrameLayout(this);

2. Create a AndroidManifest.xml for the debug variant and declare the TestActivity. This is required to start the TestActivity when testing. Add this Manifest to the debug variant in src/debug/AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
        <activity android:name="your.package.TestActivity"/>

3. Create the FragmentTestRule in the androidTest variant at src/androidTest/java/your/test/package/FragmentTestRule.java:

public class FragmentTestRule<F extends Fragment> extends ActivityTestRule<TestActivity> {

    private final Class<F> mFragmentClass;
    private F mFragment;

    public FragmentTestRule(final Class<F> fragmentClass) {
        super(TestActivity.class, true, false);
        mFragmentClass = fragmentClass;

    protected void afterActivityLaunched() {

        getActivity().runOnUiThread(() -> {
            try {
                //Instantiate and insert the fragment into the container layout
                FragmentManager manager = getActivity().getSupportFragmentManager();
                FragmentTransaction transaction = manager.beginTransaction();
                mFragment = mFragmentClass.newInstance();
                transaction.replace(R.id.container, mFragment);
            } catch (InstantiationException | IllegalAccessException e) {
                Assert.fail(String.format("%s: Could not insert %s into TestActivity: %s",
    public F getFragment(){
        return mFragment;

4. Then you can test Fragments in isolation:

public class MyFragmentTest {

    public FragmentTestRule<MyFragment> mFragmentTestRule = new FragmentTestRule<>(MyFragment.class);

    public void fragment_can_be_instantiated() {

        // Launch the activity to make the fragment visible 

        // Then use Espresso to test the Fragment
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download