One of my QA engineers is supporting an app with a fairly large codebase and a lot of different SharedPreferences files. He came to me the other day asking how to reset the application state between test runs, as if it had been uninstalled-reinstalled.
It doesn't look like that's supported by Espresso (which he is using) nor by the Android test framework natively, so I'm not sure what to tell him. Having a native method to clear all the different SharedPreferences files would be a pretty brittle solution.
How can one reset the application state during instrumentation?
Current espresso doesn't provide any mechanism to reset application state. But for each aspect (pref, db, files, permissions) exist a solution.
Initial you must avoid that espresso starts your activity automatically so you have enough time to reset.
@Rule
public ActivityTestRule<Activity> activityTestRule = new ActivityTestRule<>(Activity.class, false, false);
And later start your activity with
activityTestRule.launchActivity(null)
For reseting preferences you can use following snippet (before starting your activity)
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();
}
You can reset preferences after starting your activity too. But then the activity may have already read the preferences.
Your application class is only started once and already started before you can reset preferences.
I have started to write an library which should make testing more simple with espresso and uiautomator. This includes tooling for reseting application data. https://github.com/nenick/espresso-macchiato See for example EspAppDataTool with the methods for clearing preferences, databases, cached files and stored files.