Quick start guide to writing Espresso UI tests on Android - Android Testing Part 4

In this tutorial we’ll be going over how to get started writing Android UI tests using Espresso. We’ll continue adding tests to the ImportantTodos app repository.

Here are a few useful resources when attempting to write Espresso tests:

To get started it is recommended to disable animations on your Android Virtual Device to avoid flakiness in your tests. To do this launch your virtual device and go to Settings > Developer Options and disable the following:

  • Window animation scale

  • Transition animation scale

  • Animator duration scale

Next you’ll want to add the following dependencies to your app/build.gradle file:

androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test:rules:1.5.0'

Then make sure this line is also listed under the android.defaultConfig block of the same app/build.gradle file:

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Now it’s time to write our first test. Navigate to the app/src/androidTest directory and add a new file called TodosIntegrationTest.kt. Within our file we can declare a new class that will contain our tests, add a rule that will launch our MainActivity class, and since our app is so simple, we can essentially write a single integration test that will cover most of the core user flows.

@RunWith(AndroidJUnit4::class)
class TodosIntegrationTest {

    @get:Rule
    val activityRule = ActivityScenarioRule(MainActivity::class.java)

    @Test
    fun addTodo_updateIt_and_deleteIt() {
        val originalTitle = "Buy chocolate chip cookies"
        val newTitle = "Buy ice cream"

        // Add list item
        onView(withId(R.id.todo_title)).perform(typeText(originalTitle))
        onView(withId(R.id.todo_save_button)).perform(click())


        onView(allOf(withId(R.id.todo_name), withText(originalTitle)))
            .check(matches(isDisplayed()))
            .perform(click())

        // Update it
        onView(withId(R.id.todo_name)).perform(replaceText(newTitle))
        onView(withId(R.id.update_button)).perform(click())
        onView(allOf(withId(R.id.todo_name), withText(newTitle)))
            .check(matches(isDisplayed()))

        // Delete it
        onView(withId(R.id.todo_name)).perform(click())
        onView(withId(R.id.delete_button)).perform(click())
        onView(withId(R.id.todos_list)).check(matches(not(hasDescendant(withText(newTitle)))))
    }
}

This was a brief introduction to using Espresso for writing integration tests on Android. I hope you found it useful and if you have any tips or suggestions please let me know down in the comments. Thank you for reading!

Previous
Previous

Becoming an Explorer

Next
Next

How to write Unit Tests for the Database Access Object on Android