Изменить локаль при выполнении теста эспрессо - PullRequest
0 голосов
/ 21 ноября 2018

Я создаю простой макет, который должен поддерживать арабский язык и макет RTL.Все отлично работаетТеперь я хочу написать тест эспрессо и утверждать, что он на самом деле показывает переведенный текст или нет.Например, для арабского языка должен отображаться текст из арабского strings.xml.

До сих пор я пробовал приведенный ниже код в качестве TestRule.

public void setLocale(Locale locale) {
        Resources resources = InstrumentationRegistry.getTargetContext().getResources();
        Locale.setDefault(locale);
        Configuration config = resources.getConfiguration();
        config.locale = locale;
        resources.updateConfiguration(config, resources.getDisplayMetrics());
    }

Приведенный выше код меняет направление макета, но незагрузка ресурсов из локализованного каталога.

Я не делаю ничего лишнего, но что-то вроде http://www.andreamaglie.com/2016/a-test-rule-for-setting-device-locale/

Я что-то упустил?

1 Ответ

0 голосов
/ 16 декабря 2018

Я создал небольшой тестовый проект , используя ссылку , которую вы указали для США и Великобритании, основные классы еще ниже, но это публичный проект, так что вы можетепросто загрузите его .
Для 'AE' вам нужно будет создать strings.xml в values-ar-rAE ( см. эту ссылку ).
Редактировать: добавлен еще один тест для каждого языка и класса MyActions.
Кредиты: MyActions с здесь , примеры тестов с здесь , возможно, вам придется остановить анимацию от разработчиканастройки (из второй ссылки и здесь )

ForceLocaleRule:

import android.content.res.Configuration;
import android.content.res.Resources;
import android.support.test.InstrumentationRegistry;

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

import java.util.Locale;

public class ForceLocaleRule implements TestRule {

    private final Locale testLocale;
    private Locale deviceLocale;

    public ForceLocaleRule(Locale testLocale) {
        this.testLocale = testLocale;
    }

    @Override
    public Statement apply(final Statement base, Description description) {
        return new Statement() {
            public void evaluate() throws Throwable {
                try {
                    if (testLocale != null) {
                        deviceLocale = Locale.getDefault();
                        setLocale(testLocale);
                    }

                    base.evaluate();
                } finally {
                    if (deviceLocale != null) {
                        setLocale(deviceLocale);
                    }
                }
            }
        };
    }

    public void setLocale(Locale locale) {
        Resources resources = InstrumentationRegistry.getTargetContext().getResources();
        Locale.setDefault(locale);
        Configuration config = resources.getConfiguration();
        config.locale = locale;
        resources.updateConfiguration(config, resources.getDisplayMetrics());
    }

}

США тест:

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.Locale;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static example.com.testlocale.MyActions.setTextInTextView;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;

@RunWith(AndroidJUnit4.class)
public class MainActivityUsTest {

    @ClassRule
    public static final ForceLocaleRule localeTestRule = new ForceLocaleRule(Locale.US);

    @Rule
    public ActivityTestRule<MainActivity> myActivityRule = new ActivityTestRule<>(MainActivity.class);

    private Context context;

    @Before
    public void setUp() {
        context = InstrumentationRegistry.getTargetContext();
    }

    @Test
    public void testAirplaneEn() {
        assertEquals("airplane", context.getString(R.string.airplane));
    }

    @Test
    public void testAirplaneEnOnView() {
        onView(withId(R.id.text_view))
                .perform(setTextInTextView(context.getString(R.string.airplane)),
                        closeSoftKeyboard());
        onView(withId(R.id.text_view))
                .check(matches(withText(containsString("airplane"))));
    }

}

Великобритания тест:

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.Locale;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static example.com.testlocale.MyActions.setTextInTextView;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;

@RunWith(AndroidJUnit4.class)
public class MainActivityGbTest {

    @ClassRule
    public static final ForceLocaleRule localeTestRule = new ForceLocaleRule(Locale.UK);

    @Rule
    public ActivityTestRule<MainActivity> myActivityRule = new ActivityTestRule<>(MainActivity.class);

    private Context context;

    @Before
    public void setUp() {
        context = InstrumentationRegistry.getTargetContext();
    }

    @Test
    public void testAirplaneEnGB() {
        assertEquals("aeroplane", context.getString(R.string.airplane));
    }

    @Test
    public void testAirplaneEnOnView() {
        onView(withId(R.id.text_view))
                .perform(setTextInTextView(context.getString(R.string.airplane)),
                        closeSoftKeyboard());
        onView(withId(R.id.text_view))
                .check(matches(withText(containsString("aeroplane"))));
    }

}

MyActions:

import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.view.View;
import android.widget.TextView;

import org.hamcrest.Matcher;

import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static org.hamcrest.CoreMatchers.allOf;

public class MyActions {

    public static ViewAction setTextInTextView(final String value){
        return new ViewAction() {
            @SuppressWarnings("unchecked")
            @Override
            public Matcher<View> getConstraints() {
                return allOf(isDisplayed(), isAssignableFrom(TextView.class));
            }

            @Override
            public void perform(UiController uiController, View view) {
                ((TextView) view).setText(value);
            }

            @Override
            public String getDescription() {
                return "set text to TextView";
            }
        };
    }

}

values-en-rUS \ strings.xml

<resources>
    <string name="app_name">TestLocale</string>
    <string name="airplane">airplane</string>
</resources>

values-en-rGB \ strings.xml

<resources>
    <string name="app_name">TestLocale</string>
    <string name="airplane">aeroplane</string>
</resources>
...