Skip to content

UI testing

UI tests are a part of instrumentation tests.
That's why everything from Instrumented tests topic is applicable to UI testing.

Ui testing goal is to check some scenarios of using your application.
Usually, we do ui testing for some common users scenario:

  • Login to your application
  • Process of ordering
  • Creating new chat
  • And so on

Simple Ui test can't catch the problem with wrong padding or wrong color of your view (only in cases where you specially check that) - because there is another type of tests used to catch such problems called Screenshot testing - you can read Screenshot testing article to get familiar with that.

So, if once we decided that we need to check users scenarios - we should definitely start writing Ui tests and let's start with tools, that will help us to write this type of tests.

Main tool - Espresso and UiAutomator

Nowadays there is no doubt - for native UI testing on Android we should use Espresso for testing your application.
This is a main tool that allow us to make every test possible to access your codebase. That means tests with Espresso allow us to write white-box tests.
But you still able to write black-box tests or even gray-box with Espresso.

Why Espresso is so cool? It is synchronized with the main thread of your app and performs action only when main thread is in idle state.
It makes Espresso extremely reliable and stable (than any other existing tool) for Ui testing on Android.

Keep in mind that everything that isn't related to your app (for example, permission dialogs, volume +/- buttons, home button and etc) - can't be accessed directly within Espresso.
But don't worry - you can use UiAutomator for that purpose, and it can be called directly from test, written in Espresso.
UiAutomator is a slower tool and can support tests only in black-box style, but it can test everything outside your application on your phone.
Many cross-platforms tools for testing using UiAutomator.

These two tools are the main tools that everyone using for Ui testing on Android.
Remember, it's possible to create tests that will use both frameworks. For example, you can find your views and interact with them by Espresso and in the same test call UiAutomator to perform something specific, like pressing volume button.
But for usual testing you should prefer Espresso rather then UiAutomator.

Espresso as well as the Jetpack Compose Testing Library support Robolectric, while UiAutomator doesn't. That means, one can write Shared Tests written in Espresso or with Compose Library.

Espresso

➕ Access to codebase
➕ Very fast and more stable than UiAutomator
➖ Can't perform OS actions
➖ Can't do anything outside your application

UiAutomator

➕ Can do action outside your application
➖ Much fewer abilities to find the views and interact with them
➖ Slower and less stable than Espresso
➖ Nowadays it shouldn't be a problem but still, it's requires minSdk >= Android 4.3 (API level 18)

You can read more about both frameworks at official documentation. Espresso UiAutomator

Writing test on Espresso

Let's get familiar with Espresso.
Basically to start writing Ui tests we should:

  • Find the View (using ViewMatchers)
  • Interact with that View (using ViewInteraction)
  • Check state of View (using ViewAssertion)

Let's start with the basic test.
We have activity with one button (and no text shown), once we press it - text "Button pressed" shown.
alt text alt text
1. We should specify which activity we should run.

import androidx.test.ext.junit.rules.ActivityScenarioRule
import org.junit.Rule
...
    @get:Rule
    var activityRule: ActivityScenarioRule<MainActivity>
            = ActivityScenarioRule(MainActivity::class.java)
2. Create test and find our button (with onView() method and withId assertion by id)
    @Test
    fun pressButtonAndCheckText() {
        onView(withId(R.id.button))
    }

Disclaimer

Important addition - when you are trying to find some View that, for example, has same id like another View on that screen (that situation usually happens when you are trying to test screens with RecyclerView) you can add more Matchers Simply place all Matchers that apply to single View on your screen inside of allOf() method It will look like that


@Test
fun someTest() {
   onView(allOf(withId(R.id.button), withText("Click me")))
}

3.Then we should perform click on it (with click() method from ViewInteraction)

    @Test
    fun pressButtonAndCheckText() {
        onView(withId(R.id.button))
            .perform(click())
    }
4. And finally, let's check that our text is shown (find the TextView and assert that it is displayed)
    @Test
    fun pressButtonAndCheckText() {
        ...
        onView(withId(R.id.textview))
            .check(matches(isDisplayed()))
    }
Once we run it (run it as usual test, but you should connect real phone or run emulator), we will see standard test result alt text

Final code of our test

@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {

    @get:Rule
    var activityRule: ActivityScenarioRule<MainActivity>
            = ActivityScenarioRule(MainActivity::class.java)

    @Test
    fun pressButtonAndCheckText() {
        onView(withId(R.id.button))
            .perform(click())

        onView(withId(R.id.textview))
            .check(matches(isDisplayed()))
    }
}

Espresso Cheat Sheet

Espresso is quite powerful tool with a lot of abstractions inside it.
But there is a quite famous "cheat-sheet" for Espresso, I hope it will be helpful for everybody.

alt text

From that cheat-sheet you can understand which methods you can use for finding the Views, which methods for interactions with Views and which methods for checking the data.

Something like conclusion

To be honest, there is a lot of edge-cases once you are trying to write your own tests. That's one of the reasons why that CookBook was created, so we are suggesting to read next articles to understand how to overcome many of common problems that you will face in Ui testing.
Beside that fact, that Espresso and UiAutomator are the main tools to do Ui testing on Android, you may notice at Companies experience article that almost nobody uses only these tools.

That happens because there a lot of solutions nowadays created over Espresso and UiAutomator (that means that they use these frameworks under the hood), that makes your test even more stable and readable.
Most companies do not use Espresso or UiAutomator directly, but through frameworks that wrap them under the hood:

  • Espresso
    • Kakao
    • Barista
    • Kaspresso
  • UiAutomator
    • Kaspresso (Kautomator)
  • Compose Test Library
    • Kaspresso (since 1.4.0)

For example, you can see at Page object article how people overcome problem of readability of your tests and usually prefer something like Kakao library.
Or take a look at Flakiness article where you can find information why even in Espresso our tests might be failed even if everything looks ok and test can pass from second attempt. That article will tell you which tools helps us to minimize that risks.