How to test Fragments in isolation

Brais Gabín Moreira
21 Buttons Engineering
3 min readAug 9, 2017

We all know that testing production code we write is very important. At 21 Buttons we were just testing the “pure java” code (presenters, use cases, repositories…) but soon we also started testing the UI. From the beginning we saw that we didn’t need to use integration testing. Being completely honest, we didn’t want to fight against the flaky tests that are a by-product of integration tests. What we needed were Unit UI Tests.

For Android our UI is contained inside the Activities. Espresso ActivityTestRule allows us to test the Activity easily. So, we use these two tools to test our UI in most cases but sometimes we need to test the UI in a more unitary way. We don’t want to test the whole the Activity, we just want to test a Fragment or even a View.

We are not big Fragment fans, but sometimes they are useful. In our scenario we show a feed of posts in a variety of screens. Displaying a feed is complex: there’s vertical and horizontal pagination, likes, shares and navigation to several screens… to name just a few. Thus, we need a test that is significant with only one execution. It makes no sense to add the test into every Activity that contains the Fragment. So we need to unit test Fragments.

The problem is that if we want to test a Fragment we need an Activity to contain it. So if we want to test a Fragment we have to launch an Activity and manage it. Being more specific, we have to: launch the Activity, wait for it to be created by Android, add the Fragment we want to test and wait while the Fragment finish to load. This is necessary to ensure that the Fragment is ready to receive events when we run the tests. To easily manage this we created FragmentTestRule inspired by this SO answer.

Setting up FragmentTestRule

Add the dependency to your build.gradle file:

androidTestCompile 'com.21buttons:fragment-test-rule:1.0.0'

That’s it! Now you can unit test your Fragments! … Well… I think that I need to explain it a bit more. Let’s see an example!

This is FragmentA. It has a button and when someone clicks on it a text appears on the screen. The first thing that we need to do is to add the JUnit rule that comes with this library:

This rule assures us that we’ll have a FragmentA instance ready for each test.

Now we are ready to write FragmentA test:

FragmentTestRule hides the need to launch an Activity to test a Fragment. It launches a container-Activity and adds the desired Fragment to it.

Let’s see another example:

This case is very similar but there’s a dependency with the container Activity. This Activity has to implement TextInterface or the test will crash with a ClassCastException. You can manage this case with FragmentTestRule too, but it requires a bit more work.

First of all you have to create an Activity that just implements TextInterface:

If you don’t want this Activity in your release code, add it to the debug variant. Just like any Activity, it has to be added to the AndroidManifest. If you added the Activity on the debug variant you also have to create a new AndroidManifest in your debug variant (if you haven’t yet).

We are ready to write our own tests now. We have to tell FragmentTestRule which Activity it should launch as container.

And then write our test:

That’s it, now we can test our Fragment in isolation.

FragmentTestRule library is Open Source so feel free to open issues with bugs or feature requests. And, of course, send us PR. You can find the complete sample code on the same github repository.

--

--