Измените язык/локаль приложения программно в Jetpack Compose во время тестирования инструментов/UI на Android

Приложение поддерживает 2 локали. Во время тестирования инструментов или пользовательского интерфейса я хочу протестировать определенный язык (например, EN). Ссылаясь на 6629458, я сделал функцию смены локали в котлине:

private fun setLocale(language: String, country: String) {
        val context = InstrumentationRegistry.getInstrumentation().context
        val locale = Locale(language, country)
        // here we update locale for date formatters
        Locale.setDefault(locale)
        // here we update locale for app resources
        val res: Resources = context.getResources()
        val config: Configuration = res.configuration
        config.locale = locale
        res.updateConfiguration(config, res.displayMetrics)
    }

Его можно вызвать внутри тела функции UT-теста:

    @Test
    fun uiTest () {

        composeTestRule.setContent {
            ...
        }

        setLocale("en", "EN")

        ...
    }

Однако языковой стандарт не установлен на английский, а зависит от настроек по умолчанию моего тестируемого Android-устройства. Есть ли какая-либо подсказка для этого (функция вызывается без ошибок, но языковой стандарт НЕ изменяется, как ожидалось)?

Еще один вопрос также был опубликован, но он не для тестирования пользовательского интерфейса.

0
0
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используйте stringResource() внутри тела функции тестирования пользовательского интерфейса composeTestRule.setContent{}, тогда тестовая строка будет изменяться динамически в зависимости от локальных настроек системы устройства.

    @Test
    fun uiTest() {

        var string1 = ""
        var string2 = ""
        var string3 = ""

        composeTestRule.setContent {
            string1 = stringResource(id = R.string.string1)
            string2 = stringResource(id = R.string.string2)
            string3 = stringResource(id = R.string.string3)

            AppTheme {
                TestComponent()
            }
        }

        composeTestRule.onNodeWithText(string1).assertExists("No node with this text was found.")
        composeTestRule.onNode(hasText(string2), useUnmergedTree = false).assertExists()
        composeTestRule.onNode(hasText(string3), useUnmergedTree = false).assertExists()
        ...

Как отметил @Martin Zeitler, чтобы уменьшить утомляемость, определите глобальные строковые переменные и назначьте их внутри каждой @Test.

class AppUITests {

    @get:Rule
    val composeTestRule = createComposeRule()

    // Global variables
    var string1 = ""
    var string2 = ""
    var string3 = ""

    @Test
    fun uiTest() {
        composeTestRule.setContent {
            string1 = stringResource(id = R.string.string1)
            string2 = stringResource(id = R.string.string2)
            string3 = stringResource(id = R.string.string3)

            AppTheme {
                TestComponent()
            }
        }
        ...

Посмотрите на свой вопрос, а затем на свой ответ — похоже, он не отвечает на вопрос. Я бы предложил переключить язык устройства @Before и обратно @After, чтобы собственно сменить язык; UiAutomator может это сделать. Ваш подход может иметь смысл только с тремя строками, но со многими он может стать утомительным.

Martin Zeitler 23.06.2024 07:48

@MartinZeitler: спасибо, вы имеете в виду UI Automator по этой ссылке: Developer.android.com/training/testing/other-comComponents/…?

lhchuopp 24.06.2024 23:49

Запуск команд adb из тестового примера кажется лучшим доступным вариантом, который даст тот же результат, но при этом не придется возиться с автоматизацией пользовательского интерфейса (тест выполняется быстрее, экран не мерцает): stackoverflow.com /questions/21712205/…

Martin Zeitler 28.06.2024 13:23

Другие вопросы по теме