9

Einer meiner QA-Ingenieure unterstützt eine App mit einer ziemlich großen Codebasis und viele verschiedene SharedPreferences-Dateien. Er kam neulich zu mir und fragte, wie man den Anwendungsstatus zwischen Testläufen zurücksetzt, so als wäre er deinstalliert worden - neu installiert.Reset App-Status zwischen InstrumentationTestCase läuft

Es sieht nicht so aus, als ob es von Espresso unterstützt wird (was er benutzt) und auch nicht vom Android-Test-Framework, daher bin ich mir nicht sicher, was ich ihm sagen soll. Eine native Methode zum Löschen aller verschiedenen SharedPreferences-Dateien wäre eine ziemlich spröde Lösung.

Wie kann man den Applikationsstatus während der Instrumentierung zurücksetzen?

Antwort

15

Der aktuelle Espresso bietet keinen Mechanismus zum Zurücksetzen des Anwendungsstatus. Aber für jeden Aspekt (Pref, DB, Dateien, Berechtigungen) existiert eine Lösung.

Zunächst müssen Sie vermeiden, dass Espresso Ihre Aktivität automatisch startet, damit Sie genügend Zeit haben, um zurückzusetzen.

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

Und später Ihre Aktivität mit

activityTestRule.launchActivity(null) 

beginnen Voreinstellungen für Reseting Sie Schnipsel folgenden (vor dem Start Ihrer Tätigkeit)

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

Sie können auch Einstellungen zurücksetzen können Ihre Aktivität nach dem Start . Aber dann hat die Aktivität vielleicht schon die Präferenzen gelesen.

Ihre Anwendungsklasse wird nur einmal gestartet und ist bereits gestartet, bevor Sie die Einstellungen zurücksetzen können.

Ich habe angefangen, eine Bibliothek zu schreiben, die Tests mit Espresso und uiautomator einfacher machen sollte. Dies beinhaltet Tools zum Zurücksetzen von Anwendungsdaten. https://github.com/nenick/espresso-macchiato Siehe zum Beispiel EspAppDataTool mit den Methoden zum Löschen von Einstellungen, Datenbanken, zwischengespeicherten Dateien und gespeicherten Dateien.

+0

Das Projekt nutzt viele verschiedene SharedPreferences Dateien. Wie ich schon sagte, eine native Methode zum Löschen aller verschiedenen SharedPreferences-Dateien wäre eine ziemlich spröde Lösung. :( – Turnsole

+0

Es ist gleich, wenn Sie eine oder 9999 tausend SharedPreferences haben. Normalerweise befinden sie sich alle in shared_prefs. Was sonst erwarten Sie? Als Alternative können Sie ein Skript schreiben, um jeden Test einzeln auszuführen, zwischen jedem Test löschen Sie die Anwendungsdaten mit adb und starte dann den nächsten Test – nenick

+1

Oh, ich sehe was du da gemacht hast Ich habe es zu schnell gelesen und dachte "shared_prefs" war eine Abkürzung für your_pref_file_name_here, aber das ist buchstäblich der Stammordner der SharedPreferences Dateien. – Turnsole

0

Verbesserung auf @ Nenick-Lösung, kapseln das Zustand Clearing-Verhalten in einem benutzerdefinierten ActivityTestRule. Wenn Sie dies tun, können Sie zulassen, dass der Test die Aktivität automatisch startet, ohne dass Sie eingreifen müssen. Mit einer benutzerdefinierten ActivityTestRule ist die Aktivität bereits in dem gewünschten Status, wenn es für den Test gestartet wird.

Unten ist eine implementiert, um sicherzustellen, dass die App beim Start der Aktivität pro Test abgemeldet wird. Bei einigen Tests wurde die App in einem angemeldeten Zustand verlassen. Dies würde dann später Tests führen auch scheitern, weil die späteren angenommen, sie würden sich anmelden müssen, aber die App bereits angemeldet würden.

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

}