Android Gradle plugin with Test Fixtures support

I want to thank Nelson Osacky, Danny Preussler and Jeroen Mols for proofreading and comments on improving this article.

Photo by Sergey Zolkin from Unsplash

(The main purpose of the example source in the article is to demonstrate the problem with sharing test sources or resources between modules)

Assume that you have a module that deals with user data — users. It probably has a class like

And you have another module — login — where it shows the user first name on the lock screen — “Hi <user.firstName>, please log in to see your app personal data”.

While you’re writing the tests around the login, you probably mock/fake the dependencies from the user module. And you have to create quite often different kinds of users with slightly changed properties. Usually, we have helper functions like:

If you call this function, you get some default constructed user. It is also flexible so that you can change one property that is important for your current test. This function belongs to the test source of the login module where you’re writing tests. BTW, such code (and/or resources) you want to share between tests of different modules is called Test Fixtures.

The problem comes when you have more modules depending on the user module and you want to use the same test fixtures in these modules as well. Unfortunately, the test code is accessible from the module that it belongs. There are a few solutions to this like duplicating such functions to other modules or creating a sophisticated modules’ structure. However, it is not scalable well (at least from my experience).

We have a solution now supported by our tooling.

Gradle released test fixtures support for Java modules in the past.

However, our Android modules deal with Android Gradle plugin (I use AGP later in this article) and not with Java modules.

AGP 7.0 API has class TestFixtures, and I started checking what is already possible to do with test fixtures in the project. However, support is limited. You can already use Java test fixtures via the Gradle command-line build. The latest (Chipmuk alpha06 version) Android Studio can also autocomplete Kotlin test fixture classes. However, the further test run will fail with compilation. Hopefully, full support with Kotlin and lint will land in AGP 7.1 version.

Yeah, it is a painful experience now without Kotlin support. But you can start with Java test fixtures and convert them to Kotlin later.

To ship test fixtures from your library, you must use the latest canary AGP. And enable it first in the build.gradle:

Create test fixtures source set in the current module (again notice only Java now):

Create a fixture, for example:

After this step you can create fixtures binary

After this, you can find the additional artifact <module>-debug-testFixtures-testFixtures.aab in the build output folder and if you check inside you will see the test fixture code inside. If you’re a library creator, you can also distribute this artifact over maven.

To use test fixtures in the another module you define it in the Gradle as dependency:

And after you can reference it in your tests:

That is it!

You can also follow the Google issue ticket for updates.

You can find my test project with fixture usage here. The database module provides test fixtures and the core is consuming them.

I will keep the article updated while the tooling is progressing.

If you like the article, you can follow me on twitter.

Best!

The loving XP husband and Android developer @TripActions, ex-@Yolt