Testing Android Architecture Components

Learn how to test the Architecture Components library included in the Android Jetpack suite released in 2017 by Google’s Android Team. By Enzo Lizama.

Leave a rating/review
Download materials
Save for later
Share

At the 2017 Google I/O event, the Android team released Android Jetpack, a suite of libraries to help developers follow best practices, reduce boilerplate code and write code that works consistently across Android versions and devices.

Since then, Android developers have adopted those libraries to increase their productivity and their code quality, but testing using the new libraries is complicated. In this tutorial, you’ll learn how to test Android Jetpack’s Architecture Components libraries.

You’ll take a deep look into Android Architecture Components testing techniques by working on RWQuotes, a simple app that allows you to create and read famous quotes in local storage. In the process, you’ll learn about:

  • Basic testing concepts
  • The testing tools available for Android
  • How to test ViewModel and LiveData
  • Testing Room database operations and migrations

Now, you’ll get started by taking a look at the project.

Note: This tutorial assumes you know how to build an Android app and are familiar with the Kotlin language. If you’re not, check out our Android beginner path.

Getting Started

Download the materials for this tutorial by clicking the Download Materials button at the top or bottom of this tutorial page. Extract the ZIP file and open the start project in Android Studio. Please check that you have the latest stable version.

Once the Gradle tasks complete, build and run and you’ll see RWQuotes’ home screen.

RWQuotes home page with two quotes displayed

Here’s a look at the project structure:

Project structure

Inside the data folder, you’ll find:

  • Quote.kt: A data class that represents the entity you’ll store in the database.
  • QuoteDao.kt: An abstract class where you define the database interactions with annotations like @Query, @Insert, @Delete and @Update.
  • Migrations.kt: Stores the migration values from different versions.
  • RWQuotesDatabase.kt: Creates the Room database, allows you to get the instance for that, and manages the migrations and the prepopulated data.
  • QuoteRepositoryImpl.kt: Implements QuoteRepository.kt and uses QuoteDao.kt to perform the CRUD operations.

Next, you have ui, which stores everything related to the views and user interactions. Within that folder, you’ll find >ui/viewmodel, which contains everything related to LiveData and ViewModel. The data request for QuoteRepository.kt is here.

Finally, you’ll see RWQuoteApplication.kt, which is an application class that initializes the debugger when you’re in develop mode.

So now that you have a good idea of how the project is set up, it’s time to take a moment to understand the architecture components you’ll work with throughout this tutorial.

What Are Android Architecture Components?

Android architecture components are a collection of libraries that help you design robust, testable and maintainable apps.

In this tutorial, you’ll use the following classes to manage your UI component lifecycle and handle data persistence:

  • LiveData helps you build data objects that notify views when the underlying database changes.
  • ViewModel stores UI-related data that isn’t destroyed on app rotations.
  • Room is an SQLite object mapping library. Use it to avoid boilerplate code and easily convert SQLite table data to Java objects. Room provides compile time checks of SQLite statements and can return RxJava, Flowable and LiveData observables.
Note: If you’d like more information about how Android architecture components work, check out Android Jetpack Architecture Components: Getting Started.

Structuring Your Tests

Users interact with apps on a variety of levels, from pressing a button to downloading information onto their device. To make sure that every function works, you should test a variety of use cases and interactions as you iteratively develop your app.

The image below shows the Testing Pyramid, showing the three categories of tests you should include in your app’s test suite:

A pyramid containing three layers: unit tests at the bottom, integration tests in the middle, and UI tests at the top

As you work up the pyramid from small tests to large tests, each test increases fidelity but also increases in execution time and effort to maintain and debug. Therefore, you should write more unit tests than integration tests, and more integration tests than UI tests.

Testing on Android

By default, when you create a new Android project on Android Studio, it will create two folders for testing: androidTest and test. androidTest contains tests that run on real or virtual devices. These include integration tests, end-to-end tests and other tests where the JVM alone cannot validate your app’s functionality.

test contains tests that run on your local machine, such as unit tests.

There are many libraries that simplify the testing process. Here are the most popular for Android development testing:

  • JUnit: The most popular and widely-used unit testing framework for Java.
  • Mockito: Helps you configure mock objects to return specific values when you invoke them.
  • Espresso: Use Espresso to write concise, beautiful and reliable Android UI tests.
  • Robolectric: A framework that brings fast and reliable unit tests to Android. Tests run inside the JVM on your workstation in seconds.

If you’re unfamiliar with them, check out these tutorials:

For this tutorial, you’ll make unit tests for ViewModel and LiveData and integration tests for the Room database. These tests have something in common: You’ll use a special Rule, InstantTaskExecutorRule, to make architecture component testing easy as possible.

Here’s how it looks:

@get:Rule
val instantTaskExecutorRule = InstantTaskExecutorRule()

This is a JUnit test rule that swaps the background executor used by the architecture components with a different one that executes each task synchronously. This rule is commonly used for host-side tests that use architecture components. You’ll use this rule going forward to make it easier to create tests.

Now that you know some useful concepts about Android testing, it’s time to get started creating your test.

Testing ViewModel and LiveData

Start by creating a new test class by right-clicking on the test package and selecting New ▸ Kotlin File/Class. Name the new class QuotesViewModelTest and add the following to it:

// 1
@RunWith(AndroidJUnit4::class)
class QuotesViewModelTest {

  // 2
  @Mock
  private lateinit var viewModel: QuotesViewModel

  @Mock
  private lateinit var isLoadingLiveData: LiveData<Boolean>

  @Mock
  private lateinit var observer: Observer<in Boolean>

  // 3
  @get:Rule
  var instantExecutorRule = InstantTaskExecutorRule()

  // 4
  @Before
  fun setup() {
    MockitoAnnotations.initMocks(this)
    viewModel = spy(QuotesViewModel(ApplicationProvider.getApplicationContext(),
        QuotesRepositoryImpl(ApplicationProvider.getApplicationContext())))
    isLoadingLiveData = viewModel.dataLoading
  }

  // Your tests go here ...
}

Before starting to create your tests, you need to set everything up to make the tests work as expected. So, here’s what you do in the code above:

  1. You need to annotate the class to run with AndroidJUnit4, which is a cross-environment JUnit4 runner for Android tests. This implementation will delegate to the appropriate runner based on the value the build system provides.
  2. Mark the necessary fields as @Mock to allow shorthand mock creation and minimize repetitive mock creation code.
  3. Define the InstantTaskExecutorRule to run any executors synchronously
  4. Finally, in the setup function marked as @Before, you initialize the mocks for the tests and assign values for others. The following tests have to go below this code.

Next, you’ll write a test that verifies that the progress state triggers within your ViewModel.