Daniel Talks Code

View Original

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!