Test the Cupcake App

1. Introduction

In the Navigate between screens with Compose codelab, you learned how to add navigation to a Compose app using the Jetpack Navigation Compose component.

The Cupcake app has multiple screens to navigate through and a variety of actions that can be taken by the user. This app provides a great opportunity for you to hone your automated testing skill! In this codelab, you will write a number of UI tests for the Cupcake app and learn how to approach maximizing test coverage.

Prerequisites

What you'll learn

  • Test the Jetpack Navigation component with Compose.
  • Create a consistent UI state for each UI test.
  • Create helper functions for tests.

What you'll build

  • UI tests for the Cupcake app

What you'll need

  • The latest version of Android Studio
  • An internet connection to download the starter code

2. Download the starter code

  1. In Android Studio, open the basic-android-kotlin-compose-training-cupcake folder.
  2. Open the Cupcake app code in Android Studio.

3. Set up Cupcake for UI tests

Add the androidTest dependencies

The Gradle build tool enables you to add dependencies for specific modules. This functionality prevents dependencies from being compiled unnecessarily. You are already familiar with the implementation configuration when including dependencies in a project. You've used this keyword to import dependencies in the app module's build.gradle.kts file. Using the implementation keyword makes that dependency available to all source sets in that module; at this point in the course, you gained experience with the main, test, and androidTest source sets.

UI tests are contained in their own source sets called androidTest. Dependencies that are only needed for this module don't need to be compiled for other modules, such as the main module, where the app code is contained. When adding a dependency that is only used by UI tests, use the androidTestImplementation keyword to declare the dependency in the app module's build.gradle.kts file. Doing so ensures that the UI test dependencies are compiled only when you run UI tests.

Complete the following steps to add the dependencies necessary to write UI tests:

  1. Open the build.gradle.kts(Module :app) file.
  2. Add the following dependencies to the dependencies section of the file:
androidTestImplementation(platform("androidx.compose:compose-bom:2023.05.01"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
androidTestImplementation("androidx.navigation:navigation-testing:2.6.0")
androidTestImplementation("androidx.test.espresso:espresso-intents:3.5.1")
androidTestImplementation("androidx.test.ext:junit:1.1.5")

Create the UI test directory

  1. Right-click the src directory in the project view and select New > Directory.

290b1ab99ce8f4e5.png

  1. Select the androidTest/java option.

718bde5eb21b4f6f.png

Create the test package

  1. Right-click the androidTest/java directory in the project window, and select New > Package.

7ad315f41e2b0881.png

  1. Name the package com.example.cupcake.test. b8306f9d11988a2.png

Create the navigation test class

In the test directory, create a new Kotlin class called CupcakeScreenNavigationTest.

5515db35968f7d86.png4b527e7404fad927.png

4. Set up the nav host

In a previous codelab, you learned that UI tests in Compose require a Compose test rule. The same is true of testing Jetpack Navigation. However, testing navigation requires some additional setup through the Compose test rule.

When testing Compose Navigation, you won't have access to the same NavHostController that you do in the app code. However, you can use a TestNavHostController and configure the test rule with this nav controller. In this section, you learn how to configure and reuse the test rule for navigation tests.

  1. In CupcakeScreenNavigationTest.kt, create a test rule using createAndroidComposeRule and passing ComponentActivity as the type parameter.
import androidx.activity.ComponentActivity
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import org.junit.Rule

@get:Rule
val composeTestRule = createAndroidComposeRule<ComponentActivity>()

To make sure that your app navigates to the correct place, you need to reference a TestNavHostController instance to check the navigation route of the nav host when the app takes actions to navigate.

  1. Instantiate a TestNavHostController instance as a lateinit variable. In Kotlin, the lateinit keyword is used to declare a property that can be initialized after the object has been declared.
import androidx.navigation.testing.TestNavHostController

private lateinit var navController: TestNavHostController

Next, specify the composable you want to use for the UI tests.

  1. Create a method called setupCupcakeNavHost().
  2. In the setupCupcakeNavHost() method, call the setContent() method on the Compose test rule you created.
  3. Inside of the lambda passed to the setContent() method, call the CupcakeApp() composable.
import com.example.cupcake.CupcakeApp