在 Android 上进行单元测试期间的语言环境

Posted

技术标签:

【中文标题】在 Android 上进行单元测试期间的语言环境【英文标题】:Locale during unit test on Android 【发布时间】:2013-05-21 13:03:17 【问题描述】:

我有一些代码要测试。我想检查一个字符串是否由我在资源中拥有的​​各种字符串正确组成。这里的挑战是处理我的资源中的多个翻译。我知道在测试桌面应用程序时语言环境可能是一个问题,建议您创建独立于语言环境的测试。

我发现您可以通过编程方式设置语言环境,但不建议这样做(请参阅Change language programmatically in android)。虽然这个问题的目的是在正常运行应用程序时在运行时更改语言环境,但我想知道是否有更好的解决方案来解决我的问题。

【问题讨论】:

我也对此感兴趣,因此获得了赏金。我的细节:我在 Eclipse 中进行测试,我希望能够在一个套件中尽可能顺利地更改语言环境,包括时区。我想在答案中看到一个可行的例子。 @MattGibson 我用一个工作示例更新了我的答案。它会更改日期格式化程序和应用程序资源的语言环境。 【参考方案1】:

如果只是为了测试,那么您可以通过编程方式更改语言环境而不会出现任何问题。它将更改您的应用程序的配置,您将能够使用新的语言环境测试您的代码。它具有与用户更改它相同的效果。如果您想自动化您的测试,您可以编写一个脚本,使用 adb shell 更改语言环境为 described here,然后启动您的测试。

以下是测试“取消”一词在英语、德语和西班牙语语言环境中的翻译示例:

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


以下是 Eclipse 中的执行结果:

Android O 更新。

在 Android O 中运行时,应使用Locale.setDefault(Category.DISPLAY, locale) 方法(更多详细信息请参见behaviour changes)。

【讨论】:

我没有使用 AndroidTestCase 扩展我的测试,所以我无法获取上下文。我正在使用@RunWith(RobolectricGradleTestRunner.class)。所以看起来我不能使用相同的解决方案。有什么建议吗? @PKuijpers 在 Robolectric 中,您需要在测试配置中使用限定符覆盖区域设置。请参阅robolectric.org/using-qualifiers 了解更多信息。 请尝试在拆卸方法中重置语言环境,以避免遇到问题。【参考方案2】:

当前接受的答案对我没有帮助。 但是@Dennis 的评论帮我解决了这个问题。

使用 Robolectric 并通过指定资源限定符覆盖区域设置。

为德语添加例如@Config(qualifiers="de-port")

@Test
@Config(qualifiers = "de-port")
fun testGetLocaleGerman()  ...   

Robolectrics Documentation

【讨论】:

以上是关于在 Android 上进行单元测试期间的语言环境的主要内容,如果未能解决你的问题,请参考以下文章

在 NodeJS + Typescript AWS Lambda 上进行单元测试

单元测试布道之二:在全新的 DDD 架构上进行单元测试

技术分享|单元测试推广与实战-在全新的DDD架构上进行单元测试

使用 eclipselink 在 JPA 对象上进行 jaxb 编组期间的日期对话错误

教你使用ProtoBuf,通过gRPC服务在Android上进行网络请求

在 PayPal 重定向到付款期间,客户在退货时失去会话 - 在平板电脑/Android 上