I am developing automated tests for an android application (using Robotium). In order to ensure the consistency and reliability of tests, I would like to start each test with clean state (of the application under test). In order to do so, I need to clear the app data. This can be done manually in Settings/Applications/Manage Applications/[My App]/Clear data
What is the recommended way to get this done programmatically?
This question is related to
android
you can clear SharedPreferences app-data with this
Editor editor =
context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE).edit();
editor.clear();
editor.commit();
and for clearing app db, this answer is correct -> Clearing Application database
If you have just a couple of shared preferences to clear, then this solution is much nicer.
@Override
protected void setUp() throws Exception {
super.setUp();
Instrumentation instrumentation = getInstrumentation();
SharedPreferences preferences = instrumentation.getTargetContext().getSharedPreferences(...), Context.MODE_PRIVATE);
preferences.edit().clear().commit();
solo = new Solo(instrumentation, getActivity());
}
What is the recommended way to get this done programmatically?
The only possible option is to run ADB command adb shell pm clear package
before the test. The biggest problem is that it's kind of headache combining tests execution and shell commands.
However, we (at Mediafe) came with some solution that can work for you on regular unrooted device. All you need to do is to add an annotation. All the rest is done by running simple bash script.
Just add @ClearData
annotation before ANY of your tests and tada , ADB clear command will be executed before the test execution.
This is an example of such test:
@Test
@ClearData
public void someTest() {
// your test
}
The idea is as follows
adb shell am instrument -e log true
Using the same idea these are all options you can easily support:
Use only annotations. Like this:
@Test
@ClearData
@Tags(tags = {"sanity", "medium"})
@Parameterized.Repeat(count = 3)
public void myTest() throws Exception {
String param = params[index];
// ...
}
Bonus! For each failed test:
In general, it's easy to add more options, since the tests are executed one by one from bash script rather than from gradle task.
The full blog post: https://medium.com/medisafe-tech-blog/running-android-ui-tests-53e85e5c8da8
The source code with examples: https://github.com/medisafe/run-android-tests
Hope this answers 6 years question ;)
The Simplest way to do this is
private void deleteAppData() {
try {
// clearing app data
String packageName = getApplicationContext().getPackageName();
Runtime runtime = Runtime.getRuntime();
runtime.exec("pm clear "+packageName);
} catch (Exception e) {
e.printStackTrace();
}
}
This will clear the data and remove your app from memory. It is equivalent to clear data option under Settings --> Application Manager --> Your App --> Clear data.
This will remove the data completely as well as force close the app
You can use the package-manager tool to clear data for installed apps (similar to pressing the 'clear data' button in the app settings on your device). So using adb you could do:
adb shell pm clear my.wonderful.app.package
if android version is above kitkat you may use this as well
public void onClick(View view) {
Context context = getApplicationContext(); // add this line
if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) {
((ActivityManager) context.getSystemService(ACTIVITY_SERVICE))
.clearApplicationUserData();
return;
}
This way added by Sebastiano was OK, but it's necessary, when you run tests from i.e. IntelliJ IDE to add:
try {
// clearing app data
Runtime runtime = Runtime.getRuntime();
runtime.exec("adb shell pm clear YOUR_APP_PACKAGE_GOES HERE");
}
instead of only "pm package..."
and more important: add it before driver.setCapability(App_package, package_name).
Check this code to:
@Override
protected void onDestroy() {
// closing Entire Application
android.os.Process.killProcess(android.os.Process.myPid());
Editor editor = getSharedPreferences("clear_cache", Context.MODE_PRIVATE).edit();
editor.clear();
editor.commit();
trimCache(this);
super.onDestroy();
}
public static void trimCache(Context context) {
try {
File dir = context.getCacheDir();
if (dir != null && dir.isDirectory()) {
deleteDir(dir);
}
} catch (Exception e) {
// TODO: handle exception
}
}
public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
// <uses-permission
// android:name="android.permission.CLEAR_APP_CACHE"></uses-permission>
// The directory is now empty so delete it
return dir.delete();
}
Using Context,We can clear app specific files like preference,database file. I have used below code for UI testing using Espresso.
@Rule
public ActivityTestRule<HomeActivity> mActivityRule = new ActivityTestRule<>(
HomeActivity.class);
public static void clearAppInfo() {
Activity mActivity = testRule.getActivity();
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(mActivity);
prefs.edit().clear().commit();
mActivity.deleteDatabase("app_db_name.db");
}
From API version 19 it is possible to call ActivityManager.clearApplicationUserData().
((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).clearApplicationUserData();
This solution has really helped me :
By using below two methods we can clear data programatically
public void clearApplicationData() {
File cacheDirectory = getCacheDir();
File applicationDirectory = new File(cacheDirectory.getParent());
if (applicationDirectory.exists()) {
String[] fileNames = applicationDirectory.list();
for (String fileName : fileNames) {
if (!fileName.equals("lib")) {
deleteFile(new File(applicationDirectory, fileName));
}
}
}
}
public static boolean deleteFile(File file) {
boolean deletedAll = true;
if (file != null) {
if (file.isDirectory()) {
String[] children = file.list();
for (int i = 0; i < children.length; i++) {
deletedAll = deleteFile(new File(file, children[i])) && deletedAll;
}
} else {
deletedAll = file.delete();
}
}
return deletedAll;
}
Following up to @edovino's answer, the way of clearing all of an application's preferences programmatically would be
private void clearPreferences() {
try {
// clearing app data
Runtime runtime = Runtime.getRuntime();
runtime.exec("pm clear YOUR_APP_PACKAGE_GOES HERE");
} catch (Exception e) {
e.printStackTrace();
}
}
Warning: the application will force close.
Source: Stackoverflow.com