9

Один из моих инженеров по QA поддерживает приложение с довольно большой базой данных и множеством различных файлов SharedPreferences. Он пришел ко мне на днях, спрашивая, как сбросить состояние приложения между тестовыми прогонами, как если бы он был удален из системы.Сбросить состояние приложения между InstrumentationTestCase работает

Это не похоже на то, что поддерживается эспрессо (которое он использует) или базой тестов Android изначально, поэтому я не уверен, что сказать ему. Наличие собственного метода для очистки всех разных файлов SharedPreferences будет довольно хрупким решением.

Как можно сбросить состояние приложения во время контрольно-измерительной аппаратуры?

ответ

15

Современный эспрессо не предоставляет никакого механизма для сброса состояния приложения. Но для каждого аспекта (pref, db, files, permissions) существует решение.

Первоначально вы должны избегать того, чтобы эспрессо автоматически запускал вашу деятельность, чтобы у вас было достаточно времени для сброса.

@Rule 
public ActivityTestRule<Activity> activityTestRule = new ActivityTestRule<>(Activity.class, false, false); 

А потом начать свою деятельность с

activityTestRule.launchActivity(null) 

Для переустановки предпочтений вы можете использовать следующий фрагмент код (перед началом деятельности)

File root = InstrumentationRegistry.getTargetContext().getFilesDir().getParentFile(); 
String[] sharedPreferencesFileNames = new File(root, "shared_prefs").list(); 
for (String fileName : sharedPreferencesFileNames) { 
    InstrumentationRegistry.getTargetContext().getSharedPreferences(fileName.replace(".xml", ""), Context.MODE_PRIVATE).edit().clear().commit(); 
} 

Вы можете сбросить предпочтения после начала вашей деятельности слишком , Но тогда активность, возможно, уже прочитала предпочтения.

Ваш класс приложений запускается только один раз и начинается, прежде чем вы сможете сбросить настройки.

Я начал писать библиотеку, которая должна упростить тестирование с помощью эспрессо и uiautomator. Это включает в себя инструменты для перепродажи данных приложения. https://github.com/nenick/espresso-macchiato См. Например, EspAppDataTool с методами очистки предпочтений, баз данных, кешированных файлов и сохраненных файлов.

+0

Проект использует много различных SharedPreferences файлов. Как я уже сказал, наличие собственного метода для очистки всех файлов SharedPreferences будет довольно хрупким решением. :( – Turnsole

+0

Его равный, если у вас есть один или 9999 tausend SharedPreferences. Обычно они все находятся в shared_prefs. Что еще вы ожидаете? В качестве альтернативы вы можете написать скрипт для запуска каждого теста исключительно между каждыми ясными данными теста с adb и затем начните следующий тест. – nenick

+1

О, я вижу, что вы там делали. Я читал его слишком быстро, и фигура «shared_prefs» была сокращенной для your_pref_file_name_here, но это буквально корневая папка файлов SharedPreferences. – Turnsole

0

Улучшение решения @ nenick, инкапсулирование состояния очистки в пользовательском ActivityTestRule. Если вы это сделаете, вы можете позволить тесту продолжить автоматическую активацию без вмешательства со стороны вас. С обычным ActivityTestRule, действие уже находится в желаемом состоянии, когда оно запускается для теста.

Ниже приведена версия, которую я реализовал, чтобы гарантировать, что приложение будет выходить из системы, когда действие запускается за каждый тест. Некоторые тесты, когда они не удались, покинули приложение в подписанном состоянии. Это позволило бы привести к более поздние тесты также не потому, что более поздние предполагали, что они должны войти в систему, но приложение уже будет подписан в.

public class SignedOutActivityTestRule<T extends Activity> extends ActivityTestRule<T> { 

    public SignedOutActivityTestRule(Class<T> activityClass) { 
     super(activityClass); 
    } 

    @Override 
    protected void beforeActivityLaunched() { 
     super.beforeActivityLaunched(); 
     InstrumentationRegistry.getTargetContext() 
       .getSharedPreferences(
         Authentication.SHARED_PREFERENCES_NAME, 
         Context.MODE_PRIVATE) 
       .edit() 
       .remove(Authentication.KEY_SECRET) 
       .remove(Authentication.KEY_USER_ID) 
       .apply(); 
    } 

}