androidunit-testingglobalization

Locale during unit test on Android


I have some code I want to test. I want to check if a String is properly composed out of various strings that I have in resources. The challenge here is to deal with multiple translations in my resources. I know that locale can be an issue when testing a desktop application and that it is recommended that you create locale-independent tests.

I've found that you can set the locale programatically, but it was not recommended (see Change language programmatically in Android). While this question is aimed at changing locale at runtime when running an app normally, I was wondering if there was a better solution to my problem.


Solution

  • If it's just for testing, then you can change the locale programmatically without any issues. It will change the configuration of your app and you will be able to test your code with the new locale. It has the same effect as if a user has changed it. If you want to automate your tests, you can write a script that changes locale using adb shell as described here, and launch your tests afterwards.

    Here is an example of testing translations of word "Cancel" for English, German and Spanish locales:

    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);
        }
    
    }
    

    Here are the execution results in Eclipse:

    enter image description here

    Android O update.

    When running in Android O method Locale.setDefault(Category.DISPLAY, locale) shall be used (see behaviour changes for more detail).