Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android change locale for tests

Tags:

android

kotlin

I want to test whether the strings are updated correctly when the user changes the language. I am using Espresso to test whether the string matches the correct locale and I am currently changing it like so:

private fun changeLocale(language: String, country: String) {
    val locale = Locale(language, country)
    Locale.setDefault(locale)
    val configuration = Configuration()
    configuration.locale = locale
    context.activity.baseContext.createConfigurationContext(configuration)


    getInstrumentation().runOnMainSync {
        context.activity.recreate()
    }

}

The problem is that the espresso test onView(withText(expected)).check(matches(isDisplayed())) is asserting false so I was wondering what is the correct way to set the default locale before running a test?

like image 338
Rgfvfk Iff Avatar asked Nov 01 '25 07:11

Rgfvfk Iff


2 Answers

according to this answer, you can change the Locale programmatically:

public class ResourcesTestCase extends AndroidTestCase {

    private void setLocale(String language, String country) {
        Locale locale = new Locale(language, country);
        // here we update locale for date formatters
        Locale.setDefault(locale);
        // here we update locale for app resources
        Resources res = getContext().getResources();
        Configuration config = res.getConfiguration();
        config.locale = locale;
        res.updateConfiguration(config, res.getDisplayMetrics());
    }

    public void testEnglishLocale() {
        setLocale("en", "EN");
        String cancelString = getContext().getString(R.string.cancel);
        assertEquals("Cancel", cancelString);
    }

    public void testGermanLocale() {
        setLocale("de", "DE");
        String cancelString = getContext().getString(R.string.cancel);
        assertEquals("Abbrechen", cancelString);
    }

    public void testSpanishLocale() {
        setLocale("es", "ES");
        String cancelString = getContext().getString(R.string.cancel);
        assertEquals("Cancelar", cancelString);
    }

}

you can easily convert that code to Kotlin.

like image 116
Adib Faramarzi Avatar answered Nov 02 '25 20:11

Adib Faramarzi


In my experience, setting locale at runtime is simply not reliable. This guy has a lot more to say about the topic here: https://proandroiddev.com/change-language-programmatically-at-runtime-on-android-5e6bc15c758

You should try using Firebase Test Lab or similar services and run your tests on different devices (which have different locales set)

like image 24
ericn Avatar answered Nov 02 '25 22:11

ericn