Espresso Testing and Screen Robots: Getting Started

In this Espresso testing tutorial you’ll learn how to create UI tests with Espresso and how to leverage Screen Robots to make them clear and maintainable. By Victoria Gonda.

4.9 (28) · 2 Reviews

Download materials
Save for later
Share

Testing your app is immensely important, but often overlooked. Sometimes this is because the developer simply doesn’t know where to start. One place you can start is by testing your UI using Espresso tests.

You can further power your Espresso test writing by using Screen Robots to take care of repetitive testing code.

In this tutorial, you will learn:

  • What UI tests are and why they are important.
  • How to use Espresso to test your UI.
  • What Screen Robots are and how they can be helpful.
Note: This tutorial assumes you have basic knowledge of Android and Kotlin. If you are new to Android Development, check out our Beginning Android Development tutorials. Need to catch up on Kotlin? Take a look at Kotlin For Android: An Introduction.

Using Espresso

Espresso is not only a delicious coffee beverage but also an entire testing framework from Google that allows you to test the UI of your Android app. Manually click-testing all parts of your app is way too slow and tedious. With Espresso, you can write automated tests to make sure everything works as expected and catch regressions before they happen.

You can speed up your test writing even more by creating Screen Robots. These are helper functions that take care of repetition you may have in your tests, such as filling out a form.

Note: UI tests are different from unit tests. Where UI tests test your app by verifying that the state of the UI is consistent after a given set of interactions with the UI. A unit test on the other hand, tend to be smaller tests that verify class method outputs or state based on a set of given input. If you’d like to read more about unit tests, check out Android Unit Testing with Mockito.

Getting Started

To learn about UI testing, you will write tests for an Emoji Tip Calculator app. This app allows you to enter the total from your bill, pick an emoji that represents how you feel about the service and get a tip amount along with the total. You also have the option to round up to the nearest dollar.

Start by downloading the sample project using the Download Materials button at the top or bottom of this tutorial. Open and build the starter project in Android Studio.

Run the app and try it out so that you know the expected behaviors. Try different dollar amounts, pick different emojis and toggle the Round up to nearest dollar switch to see what happens.

Screenshot of Emoji Calculator app

You’ll write a whole new test file for this tutorial, but it may be helpful to become familiar with some of the other files. Take a look at MainActivity.kt and activity_main.xml. These define the views and logic for the app.

Adding Dependencies

By default, a generated Android project includes some Espresso dependencies. Every new project should already include the following dependencies in app/build.gradle:

androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'

And a default test runner in the defaultConfig:

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

This should be enough for you to write UI tests, however, you will add more rule and truth assertion libraries provided by Google to reduce the boilerplate code required in tests. Add the following dependencies to app/build.gradle:

androidTestImplementation 'androidx.test:rules:1.1.1'
androidTestImplementation 'androidx.test.ext:truth:1.1.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'

Sync your .gradle files after you make that change. You can see a breakdown of what each testing dependancies provides in the Google documentation.

Note: If you don’t want to use the AndroidX helpers in your own project yet, you can still follow along with this tutorial. You’ll find the alterations needed when not using them in future notes. To understand what’s added, take a look at this blog post.

Writing Espresso Tests

First, you need a file in which to write your tests. To see the actual file structure of the project, switch to the Project view by selecting Project from the dropdown at the top of the Project window on the left.

Project Structure

Create a MainActivityTest.kt under app ‣ src ‣ androidTest ‣ java ‣ com ‣ raywenderlich ‣ android ‣ emojicalculator. It’s standard practice to put your test file under the same package structure as the file you’re testing, replacing main with androidTest, or test for non Android tests. This package structure mimics the location of MainActivity.kt, as that’s what you’re testing.

Add the empty class to your file:

class MainActivityTest {
  
}

Keep the defaults and select OK.

Create test dialog

Then, choose the androidTest directory and select OK again.
Test location dialog

Note: There’s a shortcut in Android Studio for creating this class file in this location. Place your cursor on the class declaration for MainActivity, press ⌘ + ⇧ + T (or Control + Shift + T on Windows) and select Create New Test…. A window will pop up to select the location of the test.

Finally, before writing your tests, you need to add an annotation to say what to run the tests with. Add this right above your test class declaration.

@RunWith(AndroidJUnit4::class)

Use androidx.test.ext.junit.runners.AndroidJUnit4 when prompted to import AndroidJUnit4 and org.junit.runner.RunWith to import RunWith.

This tells JUnit to run the tests inside of AndroidJUnit4 instead of the runner built into JUnit. AndroidJUnit4 is a test runner that runs JUnit style tests on Android devices. When used in Espresso tests, it controls launching the app and running UI tests.

In addition to removing that dependency, add this TestRule inside your MainActivityTest:

Note: When not using the AndroidX helpers, you don’t need this dependency in app/build.gradle:
  androidTestImplementation 'androidx.test.ext:truth:1.1.0'
@get:Rule
val activityRule = ActivityTestRule(MainActivity::class.java, false, false)
  androidTestImplementation 'androidx.test.ext:truth:1.1.0'
@get:Rule
val activityRule = ActivityTestRule(MainActivity::class.java, false, false)

Launching an Activity

When testing your UI, the first thing you need to make sure you can do is launch it! A launch test is a great first test and makes sure your app, or a specific screen, can start up without crashing. That’s important!

Test names should be clear, easy to read and should focus on telling what they are supposed to do. To achieve that, you should avoid using the word test in your test name.

Write a test that launches the MainActivity in your test class:

@Test
fun appLaunchesSuccessfully() {
  ActivityScenario.launch(MainActivity::class.java)
}

This uses the ActivityScenario to launch the MainActivity. The ActivityScenario class is a part of AndroidX and provides APIs to start and drive an Activity’s lifecycle state for testing. Use the androidx.test.core.app.ActivityScenario package when prompted to import ActivityScenario and org.junit.Test to import Test. The test will automatically fail if the app crashes for some reason.

Note: If you’re not using the helpers, replace ActivityScenario.launch() with the following anytime you need to launch the activity:
activityRule.launchActivity(null)
activityRule.launchActivity(null)

Before you run your test, you should turn off animations on your testing device. Whether it’s an emulator or physical device you’re working with, go to Settings ‣ Developer options and set all the following to off:

  • Window animation scale.
  • Transition animation scale.
  • Animator duration scale.

Build and run your test! You can do this in one of a number of ways:

  • Select the green triangle in the gutter of the test file.
  • Right-click on the test class declaration or the file name in the navigator and select Run ‘MainActivityTest’.
  • Running ./gradlew connectedAndroidTest from the command line.
  • Set up a test configuration as described here.

Passing launch test

Note: If you want to see what the test looks when it fails, temporarily add a throw RuntimeException() some place in onCreate() of MainActivity. It’s good to see your test fail: That’s how you know it’s doing its job. Just make sure you remember to fix it!