วิธีล้างข้อมูลแอปพลิเคชันทางโปรแกรม


152

ฉันกำลังพัฒนาแบบทดสอบอัตโนมัติสำหรับแอปพลิเคชัน Android (โดยใช้ Robotium) เพื่อให้มั่นใจถึงความสอดคล้องและความน่าเชื่อถือของการทดสอบฉันต้องการเริ่มต้นการทดสอบแต่ละครั้งด้วยสถานะที่สะอาด (ของแอปพลิเคชันภายใต้การทดสอบ) ในการดำเนินการดังกล่าวฉันต้องล้างข้อมูลแอพ ซึ่งสามารถทำได้ด้วยตนเองในการตั้งค่า / แอปพลิเคชัน / จัดการแอปพลิเคชัน / [แอพของฉัน] / ล้างข้อมูล

อะไรคือวิธีที่แนะนำให้ทำสิ่งนี้โดยทางโปรแกรม?


เป็นไปได้ไหมที่จะใช้เครื่องมือ adb เพื่อล้างข้อมูลระหว่างแอปพลิเคชั่นเปิดตัว? adb -w
smith324

น่าเสียดายที่ตัวเลือกนี้ใช้ไม่ได้ (ความช่วยเหลือ adb ล้าสมัย)
user597603

มันจะดีมาก เมื่อทำการดีบั๊กปัญหาฐานข้อมูลฉันต้องไปที่ตัวเลือกล้างข้อมูลอย่างมากและทำให้การไหลของฉันหยุดชะงัก
Jason Prado

วิธีที่จะทำผ่านทาง Android สตูดิโอจะกล่าวถึงที่นี่: stackoverflow.com/q/31713579/905686
user905686

ทำเช่นนี้โดยเฉพาะ: stackoverflow.com/a/57461180/94557
Matt Wolfe

คำตอบ:


171

คุณสามารถใช้เครื่องมือตัวจัดการแพคเกจเพื่อล้างข้อมูลสำหรับแอพที่ติดตั้ง (คล้ายกับการกดปุ่ม 'ล้างข้อมูล' ในการตั้งค่าแอพในอุปกรณ์ของคุณ) ดังนั้นการใช้ adb คุณสามารถทำได้:

adb shell pm clear my.wonderful.app.package

1
บน Android 2.1-update1 Error: unknown command 'clear'นี้น่าเสียดายที่อัตราผลตอบแทน
Paul Lammertsma

@Palani: ทำงานได้สำหรับฉันสำหรับรุ่นใด ๆ ข้างต้น 2.1-r1 (andoid-7) ข้อความผิดพลาดใด ๆ ?
edovino

1
คำสั่งข้างต้นเชื่อมต่อกับเชลล์ android และเรียกใช้ "pm ลบ my.wonderful.app.package" ใน android ในอุปกรณ์ของฉันคำสั่ง "pm" ไม่มีตัวเลือก "ชัดเจน" ไม่มีอะไรเกี่ยวข้องกับ sdk ขึ้นอยู่กับเฟิร์มแวร์ของอุปกรณ์
Palani

กำลังมองหาข้อมูลที่ชัดเจนของเบราว์เซอร์ (defaut) และแอปเบราว์เซอร์โครมในอุปกรณ์ Android programmaticaly จากแอพ android ของฉันโปรดช่วยด้วย ..
Brijesh Patel

ใช้งานไม่ได้กับทุกอุปกรณ์ แต่มันยอดเยี่ยมสำหรับอุปกรณ์ที่ใช้งานได้
Cory Trese

34

การติดตามคำตอบของ @ edovino วิธีการล้างการตั้งค่าทั้งหมดของแอปพลิเคชันโดยทางโปรแกรมจะเป็น

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

คำเตือน : แอปพลิเคชันจะบังคับปิด


5
หากคุณมีรหัสทดสอบใด ๆ ที่ทำงานหลังจากนี้มันจะล้มเหลว
rajath

การดำเนินการนี้ต้องมีและสิทธิ์ที่จะประกาศในรายการหรือไม่
reubenjohn

1
ไม่ไม่จำเป็นต้องได้รับอนุญาตพิเศษใด ๆ
Sebastiano

ขอบคุณคุณช่วยชีวิตฉันไว้!
Sidd

1
หากฉันไม่ต้องการบังคับให้ปิดแอพ
NJ


14

จาก API เวอร์ชัน 19 เป็นไปได้ที่จะเรียก ActivityManager.clearApplicationUserData ()

((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).clearApplicationUserData();

13
เพียงแค่ FYI การเรียกสิ่งนี้จะทำให้แอปของคุณสิ้นสุด
Zach Rattner

8

ตรวจสอบรหัสนี้เพื่อ:

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

6

หากคุณมีการตั้งค่าที่ใช้ร่วมกันเพียงสองสามรายการเพื่อล้างแล้วโซลูชันนี้จะดีกว่ามาก

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

สิ่งนี้ไม่จำเป็นต้องเปิดใช้งาน"โหมดเครื่องมือวัด"ใช่ไหม โหมดนั้นคืออะไร?
ADTC

ใช่นี่ต้องใช้แอปพลิเคชั่น "ที่ใช้เครื่องมือ" นั่นคือการทดสอบของคุณจะทำงานควบคู่ไปกับรหัสแอปพลิเคชันของคุณบนอุปกรณ์จริงที่กำลังดำเนินการอยู่ซึ่งหมายความว่าคุณสามารถเข้าถึงสถานะทั้งหมดของแอปพลิเคชันของคุณ
โทมัสเคลเลอร์

สิ่งที่ควรเป็น (... )
NickUnuchek

@NickUnuchek ชื่อของไฟล์การกำหนดค่าตามความชอบ
Thomas Keller

3

การใช้บริบทเราสามารถล้างไฟล์เฉพาะแอปเช่นการตั้งค่าไฟล์ฐานข้อมูล ฉันใช้โค้ดด้านล่างสำหรับการทดสอบ UI โดยใช้ 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");
    }

3

วิธีที่ง่ายที่สุดในการทำเช่นนี้คือ

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

วิธีนี้จะล้างข้อมูลและลบแอปของคุณออกจากหน่วยความจำ มันเทียบเท่ากับตัวเลือกการล้างข้อมูลภายใต้การตั้งค่า -> ตัวจัดการแอปพลิเคชัน -> แอปของคุณ -> ล้างข้อมูล

การดำเนินการนี้จะลบข้อมูลทั้งหมดรวมถึงบังคับปิดแอป


โปรดอย่าเพิ่มคำตอบเดียวกันในหลายคำถาม ตอบคำถามที่ดีที่สุดและทำเครื่องหมายส่วนที่เหลือเป็นรายการซ้ำ ดูเป็นที่ยอมรับหรือไม่ที่จะเพิ่มคำตอบซ้ำสำหรับคำถามหลายข้อ?
FelixSFD

1
เราจะทำสิ่งนี้ให้สำเร็จได้อย่างไรโดยไม่ปิดแอป
Omkar Ghurye

2

โซลูชันนี้ช่วยฉันได้มาก:

โดยใช้สองวิธีด้านล่างนี้เราสามารถล้างข้อมูลแบบเป็นโปรแกรม

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

2

ถ้ารุ่น android อยู่เหนือ kitkat คุณสามารถใช้มันได้เช่นกัน

โมฆะสาธารณะ onClick (ดูมุมมอง) {

    Context context = getApplicationContext(); // add this line
    if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) {
        ((ActivityManager) context.getSystemService(ACTIVITY_SERVICE))
            .clearApplicationUserData();
        return;
    }

0

อะไรคือวิธีที่แนะนำให้ทำสิ่งนี้โดยทางโปรแกรม?

ตัวเลือกเดียวที่เป็นไปได้คือการเรียกใช้คำสั่ง ADB adb shell pm clear packageก่อนการทดสอบ ปัญหาที่ใหญ่ที่สุดคือมันปวดหัวที่รวมการทดสอบการทำงานและคำสั่งเชลล์

อย่างไรก็ตามเรา (ที่ Mediafe) มาพร้อมกับโซลูชันบางอย่างที่สามารถทำงานให้คุณได้บนอุปกรณ์ที่ไม่ได้รับการรูทปกติ สิ่งที่คุณต้องทำคือการเพิ่มคำอธิบายประกอบ ส่วนที่เหลือทั้งหมดจะกระทำโดยการทำงานที่เรียบง่ายสคริปต์ทุบตี

เพียงเพิ่ม@ClearDataคำอธิบายประกอบก่อนการทดสอบใด ๆ ของคุณและ tada 🎉คำสั่ง ADB clear จะถูกดำเนินการก่อนที่จะดำเนินการทดสอบ

นี่คือตัวอย่างของการทดสอบดังกล่าว:

@Test
@ClearData
public void someTest() {
    // your test
}

แนวคิดมีดังนี้

  1. อ่านการทดสอบทั้งหมดโดยใช้ adb shell am instrument -e log true
  2. สร้างแผนการดำเนินการโดยแยกวิเคราะห์ผลลัพธ์จาก (1)
  3. เรียกใช้แผนการดำเนินการทีละบรรทัด

การใช้แนวคิดเดียวกันนี้เป็นตัวเลือกทั้งหมดที่คุณสามารถรองรับได้อย่างง่ายดาย:

  • ข้อมูลชัดเจน
  • ล้างแถบการแจ้งเตือน
  • parameterize
  • กรองและเรียกใช้ด้วยแท็ก

ใช้คำอธิบายประกอบเท่านั้น แบบนี้:

@Test
@ClearData
@Tags(tags = {"sanity", "medium"})
@Parameterized.Repeat(count = 3)
public void myTest() throws Exception {
    String param = params[index];
    // ...
}

โบนัส! 🎁สำหรับการทดสอบที่ล้มเหลวแต่ละครั้ง:

  • รวบรวม Logcat + stacktrace
  • บันทึกวิดีโอ (mp4)
  • ฐานข้อมูล (sqlite)
  • การกำหนดค่าเริ่มต้นที่ใช้ร่วมกัน Dump
  • รวบรวมไฟล์ dumpsys เช่น: แบตเตอรี่, netstats และอื่น ๆ

โดยทั่วไปแล้วมันง่ายที่จะเพิ่มตัวเลือกเพิ่มเติมเนื่องจากการทดสอบจะถูกดำเนินการทีละรายการจากสคริปต์ทุบตีแทนที่จะเป็นงานไล่ระดับ

📗 โพสต์บล็อกเต็ม : https://medium.com/medisafe-tech-blog/running-android-ui-tests-53e85e5c8da8

📘 ซอร์สโค้ดพร้อมตัวอย่าง : https://github.com/medisafe/run-android-tests

หวังว่านี้จะตอบคำถาม 6 ปี;)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.