web-dev-qa-db-fra.com

Réinitialiser l'état de l'application entre les exécutions d'InstrumentationTestCase

Un de mes ingénieurs QA prend en charge une application avec une base de code assez importante et de nombreux fichiers SharedPreferences différents. Il est venu me voir l'autre jour pour demander comment réinitialiser l'état de l'application entre les tests, comme s'il avait été désinstallé-réinstallé.

Il ne semble pas être pris en charge par Espresso (qu'il utilise) ni par le framework de test Android nativement, donc je ne sais pas quoi lui dire. Avoir une méthode native pour effacer tous les différents fichiers SharedPreferences seraient une solution assez fragile.

Comment réinitialiser l'état de l'application lors de l'instrumentation?

18
Turnsole

L'espresso actuel ne fournit aucun mécanisme pour réinitialiser l'état de l'application. Mais pour chaque aspect (pref, db, fichiers, permissions) existe une solution.

Initialement, vous devez éviter que l'expresso démarre automatiquement votre activité afin que vous ayez suffisamment de temps pour réinitialiser.

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

Et ensuite, commencez votre activité avec

activityTestRule.launchActivity(null)

Pour réinitialiser les préférences, vous pouvez utiliser l'extrait de code suivant (avant de commencer votre activité)

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

Vous pouvez également réinitialiser les préférences après avoir démarré votre activité. Mais alors l'activité peut avoir déjà lu les préférences.

Votre classe d'application n'est démarrée qu'une seule fois et déjà démarrée avant que vous puissiez réinitialiser les préférences.

J'ai commencé à écrire une bibliothèque qui devrait rendre les tests plus simples avec espresso et uiautomator. Cela comprend des outils pour réinitialiser les données d'application. https://github.com/nenick/espresso-macchiato Voir par exemple EspAppDataTool avec les méthodes pour effacer les préférences, les bases de données, les fichiers mis en cache et les fichiers stockés.

32
nenick

En améliorant la solution de @ nenick, encapsulez le comportement d'effacement d'état dans un ActivityTestRule personnalisé. Si vous procédez ainsi, vous pouvez permettre au test de continuer à lancer l'activité automatiquement sans intervention de votre part. Avec un ActivityTestRule personnalisé, l'activité est déjà dans l'état souhaité lorsqu'elle se lance pour le test.

Les règles sont particulièrement utiles car elles ne sont liées à aucune classe de test spécifique et peuvent donc être facilement réutilisées dans n'importe quelle classe de test ou tout projet.

Ci-dessous, j'en ai implémenté un pour vérifier que l'application est déconnectée au lancement de l'activité, par test. Certains tests, lorsqu'ils ont échoué, laissaient l'application dans un état signé. Cela entraînerait également l'échec des tests ultérieurs, car ceux-ci supposaient qu'ils devaient se connecter, mais l'application était déjà connectée.

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

}
9
Julian A.