Skip to main content
Version: 6.0.0

Changing the Locale in a test

API 24+​

It is often desirable to test your View or Activity in multiple locales. Testify allows you to dynamically change the locale on a per-test basis.

Please read this excellent blog post if you want to better understand how to dynamically adjust Locale in your app. Note that the Testify locale override support is intended for instrumentation testing only and does not provide a suitable solution for your production application.

To begin, if you are targeting an emulator running Android API 24 or higher, your activity under test must implement the TestifyResourcesOverride interface. This allows Testify to attach a new Context with the appropriate locale loaded. It is highly recommended that you employ a test harness activity for this purpose. Please see the TestLocaleHarnessActivity in the provided Sample.

Example Test Harness Activity

open class TestHarnessActivity : AppCompatActivity(), TestifyResourcesOverride {

/**
* This is required to correctly support dynamic Locale changes
*
* See [TestingResourceConfigurationsExampleTest]
*/
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase?.wrap())
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContentView(FrameLayout(this).apply {
layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
id = R.id.harness_root
})
}
}

ActivityTestRule vs. ActivityScenarioRule​

With an Activity which implements TestifyResourcesOverride, and if you are using ScreenshotRule (a subclass of ActivityTestRule), you can configure the locale field on method on the ScreenshotTestRule. TestifyConfiguration.locale can be set to any valid java.util.Locale instance.

If you are using ScreenshotScenarioRule (which works in conjunction with ActivityScenarioRule), you must use the overrideResourceConfiguration helper method. This method must be called before the activity is launched.

class TestLocaleActivityTest {

@get:Rule var rule = ScreenshotRule(
activityClass = TestLocaleHarnessActivity::class.java,
rootViewId = R.id.harness_root
)

@ScreenshotInstrumentation
@TestifyLayout(R.layout.view_client_details)
@Test
fun testLocaleFrance() {
rule
.configure {
locale = Locale.FRANCE
}
.assertSame()
}
}

Right-to-left layouts​

Setting a right-to-left locale, such as Arabic (ar) or Hebrew (he), also mirrors your layout. Android derives the layout direction from the locale, so views positioned with start and end swap sides, just as they do on a device set to that language.

import dev.testify.internal.helpers.overrideResourceConfiguration

class RightToLeftScreenshotTest {

@get:Rule val rule = ScreenshotScenarioRule(rootViewId = R.id.harness_root)

@ScreenshotInstrumentation
@TestifyLayout(R.layout.view_client_details)
@Test
fun testHebrew() {
overrideResourceConfiguration<TestLocaleHarnessActivity>(locale = Locale.forLanguageTag("he"))

launchActivity<TestLocaleHarnessActivity>().use { scenario ->
rule
.withScenario(scenario)
.assertSame()
}
}
}

A few things to keep in mind:

  • Your app must declare android:supportsRtl="true" on the <application> element for its layouts to mirror.
  • Text in a left-to-right script, such as English placeholder text, is still laid out left to right. Use translated strings to see text aligned the way your users see it.
  • As with any locale, the baseline is stored in a folder for that locale, for example 37-1080x2220@440dp-ar.

API 23 or lower​

On lower API levels, a test harness activity is not required. You are not required to implement TestifyResourcesOverride, but doing so is not harmful.

To test with a provided locale, invoke the setLocale method on ScreenshotRule

Example Test:

class MainActivityScreenshotTest {

@get:Rule var rule = ScreenshotRule(MainActivity::class.java)

@ScreenshotInstrumentation
@TestifyLayout(R.layout.view_client_details)
@Test
fun testLocaleFrance() {
rule
.setLocale(Locale.FRANCE)
.assertSame()
}
}