UI testing

Get access to string resources in UiAutomator

This article explains how to access string resources in UiAutomator test cases.
Alex Zhukovich 2 min read
Get access to string resources in UiAutomator
Table of Contents

String resources provide multiple benefits, such as localization and accessibility support, dynamic string formatting and maintenance of the application.

When we create UI test cases, we often want to reuse strings from the app to avoid issues when a test device has different locale than the default language of the application. Unfortunately, the "UiAutomator" doesn't allow us to get strings using the generated R class.

There are a few popular cases of using the UiAutomator framework:

We cannot verify both cases with the Espresso based framework because notifications and permission dialog are part of the OS (Operating System), not part of the application. However, when we test notifications, we use string values from resources and we want to reuse string resources to avoid failure when we update the string resource value.

Let's take a look at part of the test cases that interact with a notification:

val expectedText = TestData.getCityById(amsterdamId).description
...

uiDevice.openNotification()
uiDevice.wait(Until.hasObject(By.text("DemoApp")), TIMEOUT)
uiDevice.findObject(By.text(expectedText))
    .click()
...

The major problem in this example is the hard-coded string. Let's explore how we can use string resources with the UiAutomator framework.

The first option is to use the By.res(PACKAGE, RESOURCE_ID) function. Here, we need to pass package and resource ID as strings and we can easily make a typo.

Let's explore how to get a value from a string resources by using the R class, like R.string.app_name. To get a value from the string resource, we need to have application context, which we can get from the InstrumentationRegistry.

InstrumentationRegistry.getInstrumentation().targetContext

The next step is to create a function that returns a string value from resource id.

private fun stringResource(
    @StringRes resId: Int,
    context: Context = InstrumentationRegistry.getInstrumentation().targetContext
): String {
    return context.getString(resId)
}

Now, we can use string resources in our test case:

val expectedText = TestData.getCityById(amsterdamId).description
...

uiDevice.openNotification()
uiDevice.wait(Until.hasObject(By.text(stringResource(R.string.app_name))), TIMEOUT)
uiDevice.findObject(By.textStartsWith(expectedText))
        .click()
...

When we use string resources (R.string.*) in our test case, we have a single point of truth for our strings. In addition to that, we will have a compilation error if we will update the name of the string resource. It helps us to find and fix an error faster.

Share
More from Mobile development with Alex
Not all UI tests are the same
Android Testing

Not all UI tests are the same

The article explores different types of UI testing, such as end-to-end testing, UI testing with fake data, pixel perfection testing, and accessibility testing. The article also includes information on how to get started with UI testing in any project.
Alex Zhukovich 8 min read
How to test Android App Shortcuts
Android Testing

How to test Android App Shortcuts

The "App Shortcuts" feature allows users to access a specific part of the application from the device's home screen. Users can see all available shortcuts by long pressing on the icon of the applications. In this article, we will learn how to test app shortcuts in Android apps.
Alex Zhukovich 5 min read

Great! You’ve successfully signed up.

Welcome back! You've successfully signed in.

You've successfully subscribed to Mobile development with Alex.

Success! Check your email for magic link to sign-in.

Success! Your billing info has been updated.

Your billing was not updated.