การทดสอบการสำรองและกู้คืนข้อมูลอัตโนมัติ

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

การทดสอบการสำรองและกู้คืนอัตโนมัติช่วยให้คุณตรวจพบปัญหาเหล่านี้ก่อนที่จะเผยแพร่แอป โดยเป็นการทดสอบ JUnit 5 ที่ทำงานในคอมพิวเตอร์สำหรับการพัฒนาซอฟต์แวร์และควบคุมอุปกรณ์ที่เชื่อมต่อผ่าน Android Debug Bridge (adb) การทดสอบแต่ละครั้งจะเริ่มต้นข้อมูลแอปในอุปกรณ์ สำรองและกู้คืนแอปผ่านเฟรมเวิร์กการสำรองข้อมูลของ Android จากนั้นตรวจสอบว่าข้อมูลยังคงอยู่ครบถ้วน คุณกำหนดค่าการ ทดสอบเป็นชุดโปรแกรมทดสอบปลั๊กอิน Android Gradle (AGP) ในไฟล์บิลด์ของโมดูล

วิธีการทำงาน

ชุดโปรแกรมทดสอบการสำรองและกู้คืนมี 2 ส่วนที่ทำงานร่วมกัน ดังนี้

  • การทดสอบโฮสต์ เป็นการทดสอบ JUnit 5 ที่ทำงานในคอมพิวเตอร์สำหรับการพัฒนาซอฟต์แวร์ โดยใช้ BackupRestoreController สำหรับอุปกรณ์แต่ละเครื่องเพื่อเริ่มต้นข้อมูล สำรองและกู้คืนแอป รวมถึงตรวจสอบผลลัพธ์
  • การดำเนินการกับอุปกรณ์ เป็นคลาสที่ใช้ BackupDeviceAction ซึ่งจะทำงานในกระบวนการของแอปในอุปกรณ์ จึงอ่านและเขียนข้อมูลผ่านโค้ดของแอปเองได้ การทดสอบโฮสต์จะเรียกการดำเนินการกับอุปกรณ์ตามชื่อคลาส

เมื่อคุณเรียกใช้ชุดทดสอบ AGP จะสร้างแอปและ APK ทดสอบที่มีการดำเนินการกับอุปกรณ์ ก่อนการทดสอบแต่ละครั้ง เฟรมเวิร์กการทดสอบจะติดตั้งทั้ง APK ในอุปกรณ์แต่ละเครื่องที่การทดสอบใช้ จากนั้นล้างข้อมูลของแอป

ประเภทพื้นที่เก็บข้อมูลในตัว

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

โดเมนพื้นที่เก็บข้อมูล ข้อมูล
StorageDomain.Preference คีย์ในไฟล์ SharedPreferences
StorageDomain.Database แถวในตารางฐานข้อมูล SQLite
StorageDomain.TextFile ไฟล์ข้อความในพื้นที่เก็บข้อมูลภายในของแอป
StorageDomain.BinaryFile ไฟล์ไบนารีในพื้นที่เก็บข้อมูลภายในของแอป

หากต้องการทดสอบข้อมูลอื่นๆ เช่น ไฟล์ DataStore ให้เขียนการดำเนินการกับอุปกรณ์

รูปแบบการเดินทาง

การสำรองข้อมูลแต่ละครั้งจะใช้ค่า BackupTransportMode ตารางต่อไปนี้แสดงโหมด Transport ที่รองรับ

โหมด สถานการณ์
LOCAL การสำรองข้อมูลไปยังการรับส่งข้อมูลการสำรองข้อมูลในเครื่องของอุปกรณ์ ข้อมูลสำรองจะอยู่ในอุปกรณ์
CLOUD_ENCRYPTED การสำรองข้อมูลในระบบคลาวด์ เช่น การสำรองข้อมูลที่บันทึกลงในบัญชี Google ของผู้ใช้จากอุปกรณ์ที่มีการเข้ารหัสฝั่งไคลเอ็นต์
CLOUD_UNENCRYPTED การสำรองข้อมูลในระบบคลาวด์จากอุปกรณ์ที่ไม่มีการเข้ารหัสฝั่งไคลเอ็นต์
DEVICE_TO_DEVICE การโอนจากอุปกรณ์หนึ่งไปยังอีกอุปกรณ์หนึ่ง เช่น ผ่านสายเคเบิลหรือ Wi-Fi

LOCAL ใช้งานได้ในอุปกรณ์ที่รองรับ โหมดระบบคลาวด์และโหมดการโอนจากอุปกรณ์หนึ่งไปยังอีกอุปกรณ์หนึ่งจะสร้างข้อมูลสำรองแบบเดียวกับการดำเนินการสำรองข้อมูลแอป ใน Android Studio โดยระบบจะบันทึกข้อมูลสำรองลงในคอมพิวเตอร์สำหรับการพัฒนาซอฟต์แวร์แทนที่จะอัปโหลดหรือส่งไปยังอุปกรณ์อื่น โหมดระบบคลาวด์และโหมดการโอนจากอุปกรณ์หนึ่งไปยังอีกอุปกรณ์หนึ่งต้องใช้ Google Play services ในอุปกรณ์และบิลด์ที่แก้ไขข้อบกพร่องได้ของแอป หากกฎการสำรองข้อมูลขึ้นอยู่กับการเข้ารหัสฝั่งไคลเอ็นต์ ให้ทดสอบทั้ง 2 โหมดระบบคลาวด์

ข้อกำหนด

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

  • Gradle เวอร์ชัน 9.6.0 ขึ้นไป
  • JDK เวอร์ชัน 17 ขึ้นไป
  • อุปกรณ์หรือโปรแกรมจำลองที่ใช้ Android 12 (ระดับ API 31) ขึ้นไปซึ่งเชื่อมต่อผ่าน adb หากต้องการทดสอบการโอนระหว่างอุปกรณ์ 2 เครื่อง ให้เชื่อมต่ออุปกรณ์ 2 เครื่อง

ความเข้ากันได้

ตารางต่อไปนี้แสดงเวอร์ชันขั้นต่ำและเวอร์ชันที่แนะนำสำหรับการทดสอบการสำรองและกู้คืนอัตโนมัติ

ส่วนประกอบ เวอร์ชันขั้นต่ำ เวอร์ชันที่แนะนำ
Android Studio Rabbit 2 Canary 1 Rabbit 2 Canary 4 ขึ้นไป
ปลั๊กอิน Android Gradle (AGP) 9.5.0-alpha06 9.5.0-alpha09 ขึ้นไป
ไลบรารี androidx.test.backup 1.0.0-alpha01 1.0.0-alpha02 ขึ้นไป

AGP เวอร์ชันตัวอย่างแต่ละเวอร์ชันต้องใช้ Android Studio เวอร์ชันตัวอย่างที่ตรงกัน ดูข้อมูลเพิ่มเติมได้ที่ AGP เวอร์ชันตัวอย่าง

ตั้งค่าโปรเจ็กต์

หากต้องการเพิ่มชุดโปรแกรมทดสอบการสำรองและกู้คืนลงในโมดูลแอป ให้ทำตามขั้นตอนต่อไปนี้

เปิดใช้ Flag รุ่นทดลอง

ในไฟล์ gradle.properties ของโปรเจ็กต์ ให้เปิดใช้ชุดโปรแกรมทดสอบและการทดสอบการสำรองข้อมูล

android.experimental.testSuiteSupport=true
android.experimental.enableBackupTest=true

ประกาศชุดโปรแกรมทดสอบ

ในไฟล์ build.gradle.kts ของโมดูลแอป ให้ประกาศชุดโปรแกรมทดสอบการสำรองข้อมูลในบล็อก testOptions

android {
    testOptions {
        backupTests {
            create("backupTest")
        }
    }
}

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

  • ใช้ backupTestLibraryVersion เพื่อตั้งค่าเวอร์ชันของไลบรารี androidx.test.backup ที่ AGP เพิ่มลงในชุดทดสอบ เช่น "1.0.0-alpha02" พร็อพเพอร์ตี้นี้ไม่บังคับ หากไม่ระบุ AGP จะกลับไปใช้ไลบรารีเวอร์ชันเริ่มต้นตามเวอร์ชัน AGP
  • ใช้ targetVariants เพื่อระบุตัวแปรบิลด์ที่ชุดทดสอบจะทดสอบ เช่น targetVariants.add("demoDebug") พร็อพเพอร์ตี้นี้ไม่บังคับ หากไม่ระบุ ชุดทดสอบจะทดสอบ Variant ของ testBuildType ของโมดูล ซึ่งเป็น debug โดยค่าเริ่มต้น เราขอแนะนำให้ทดสอบ Variant ที่แก้ไขข้อบกพร่องได้ เนื่องจากโหมดการรับส่งข้อมูลในระบบคลาวด์และโหมดการโอนจากอุปกรณ์หนึ่งไปยังอีกอุปกรณ์หนึ่งต้องใช้แอปที่แก้ไขข้อบกพร่องได้

AGP จะเพิ่มไลบรารีโฮสต์ androidx.test.backup:backup-host และ JUnit 5 ลงในการทดสอบโฮสต์ โดยจะเพิ่มไลบรารีอุปกรณ์ androidx.test.backup:backup ลงใน APK ทดสอบและตั้งค่าตัวเรียกใช้การวัดประสิทธิภาพของ APK ทดสอบ

หากต้องการเพิ่มทรัพยากร Dependency อื่นๆ ให้ใช้บล็อก hostJar และ testApk ของชุดทดสอบ เช่น หากต้องการใช้ Truth ในการทดสอบโฮสต์ ให้เพิ่ม Truth ลงใน hostJar บล็อกดังนี้

create("backupTest") {
    hostJar {
        dependencies {
            implementation("com.google.truth:truth:1.4.2")
        }
    }
}

สร้างชุดซอร์ส

สร้างไดเรกทอรีชุดซอร์สที่ตรงกับชื่อชุดโปรแกรม

  • ใส่การทดสอบโฮสต์ใน src/{suiteName}/test/kotlin/
  • ใส่การดำเนินการกับอุปกรณ์ใน src/{suiteName}/androidTest/kotlin/

ตัวอย่างเช่น ชุดทดสอบชื่อ backupTest จะใช้โครงสร้างไดเรกทอรีต่อไปนี้

app/src/backupTest/
├── androidTest/
│   └── kotlin/com/example/myapp/ThemeActions.kt
└── test/
    └── kotlin/com/example/myapp/SettingsBackupTest.kt

ตรวจสอบการกำหนดค่าการสำรองข้อมูล

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

เขียนการทดสอบการสำรองและกู้คืน

เขียนการทดสอบโฮสต์ในชุดซอร์ส test ของชุดทดสอบ คลาสทดสอบแต่ละคลาสต้องมีคำอธิบายประกอบ 2 รายการ ดังนี้

  • @ExtendWith(BackupRestoreExtension::class) จะให้อุปกรณ์ที่เชื่อมต่อกับการทดสอบ
  • @BackupRestoreConfig(applicationId = "...") จะตั้งค่ารหัสแอปพลิเคชันของ แอปที่อยู่ระหว่างการทดสอบ ใช้รหัสแอปพลิเคชันของ Variant ที่คุณทดสอบ รวมถึง applicationIdSuffix

เมธอดทดสอบแต่ละเมธอดจะประกาศพารามิเตอร์ BackupRestoreController สำหรับอุปกรณ์แต่ละเครื่องที่ใช้

ทดสอบประเภทพื้นที่เก็บข้อมูลในตัว

หากต้องการทดสอบประเภทพื้นที่เก็บข้อมูลในตัว ให้เรียก runBackupRestoreFlow พร้อมข้อมูลที่จะเริ่มต้น ไดเรกทอรีสำหรับไฟล์ข้อมูลสำรอง และโหมด Transport เมธอดจะดำเนินการตามขั้นตอนต่อไปนี้ในอุปกรณ์

  1. เริ่มต้นโดเมนพื้นที่เก็บข้อมูลแต่ละโดเมน
  2. หยุดแอป
  3. สำรองข้อมูลแอป
  4. ล้างข้อมูลของแอป
  5. กู้คืนข้อมูลสำรอง
  6. ยืนยันว่าโดเมนพื้นที่เก็บข้อมูลแต่ละโดเมนมีค่าตั้งต้น

หากขั้นตอนใดขั้นตอนหนึ่งล้มเหลว เมธอดจะแสดงข้อยกเว้น ซึ่งทำให้การทดสอบล้มเหลว ตัวอย่างต่อไปนี้จะทดสอบคีย์ SharedPreferences แถว SQLite และไฟล์ภายในโดยใช้การรับส่งข้อมูลการสำรองข้อมูลในเครื่อง

package com.example.myapp

import androidx.test.backup.host.BackupRestoreConfig
import androidx.test.backup.host.BackupRestoreController
import androidx.test.backup.host.BackupRestoreExtension
import androidx.test.backup.host.BackupTransportMode
import androidx.test.backup.host.StorageDomain
import java.nio.file.Path
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.io.TempDir

@ExtendWith(BackupRestoreExtension::class)
@BackupRestoreConfig(applicationId = "com.example.myapp")
class SettingsBackupTest {

    @Test
    fun settingsSurviveBackupAndRestore(
        device: BackupRestoreController,
        @TempDir outputDir: Path,
    ): Unit = runBlocking {
        device.runBackupRestoreFlow(
            storages = listOf(
                StorageDomain.Preference(
                    prefName = "settings",
                    key = "theme",
                    value = "dark",
                ),
                StorageDomain.Database(
                    dbName = "notes.db",
                    table = "notes",
                    primaryKeyCol = "id",
                    primaryKeyVal = 1,
                    columnValues = mapOf("title" to "Groceries"),
                ),
                StorageDomain.TextFile(
                    path = "drafts/note.txt",
                    content = "Buy milk",
                ),
            ),
            outputDir = outputDir,
            mode = BackupTransportMode.LOCAL,
        )
    }
}

โปรดคำนึงถึงสิ่งต่อไปนี้เมื่อกำหนดโดเมนพื้นที่เก็บข้อมูล

  • Preference จะใช้ชื่อไฟล์ SharedPreferences โดยไม่มี .xml นามสกุล
  • TextFile และ BinaryFile จะแก้ Relative Path ที่สัมพันธ์กับ filesDir ของแอป
  • Database จะเขียนแถวด้วย SQL และสร้างตารางที่มีคอลัมน์ TEXT หากตารางไม่มีอยู่ หากแอปใช้ Room เราขอแนะนำให้ ทดสอบเนื้อหาฐานข้อมูลด้วย การดำเนินการกับอุปกรณ์ ที่ใช้ DAO เพื่อให้ฐานข้อมูลมีสคีมาที่ Room คาดหวัง

เขียนการดำเนินการกับอุปกรณ์

หากต้องการเริ่มต้นหรือยืนยันข้อมูลที่ประเภทพื้นที่เก็บข้อมูลในตัวไม่ครอบคลุม ให้เขียนการดำเนินการกับอุปกรณ์ในชุดแหล่งที่มา androidTest ของชุดทดสอบ การดำเนินการกับอุปกรณ์จะใช้ BackupDeviceAction และลบล้างสมาชิก 2 รายการ ดังนี้

  • ตั้งค่า phase เป็น BackupDeviceAction.PHASE_POPULATE สำหรับการดำเนินการที่เริ่มต้นข้อมูล หรือ BackupDeviceAction.PHASE_VERIFY สำหรับการดำเนินการที่ตรวจสอบข้อมูล
  • ใช้ execute เพื่อเรียกใช้การดำเนินการด้วย Context ของแอปและอาร์กิวเมนต์จากการทดสอบโฮสต์ แสดงผลลัพธ์ที่สร้างด้วย BackupDeviceActionResult.success หรือ BackupDeviceActionResult.failure เมธอด Factory และส่งข้อความแสดงข้อผิดพลาดไปยัง failure

เมธอด execute จะทำงานในกระบวนการของแอปในเธรดเบื้องหลัง จึงบล็อกได้จนกว่าการอ่านและการเขียนจะเสร็จสิ้น

ตัวอย่างต่อไปนี้จะเริ่มต้นและยืนยันการตั้งค่าธีมที่แอปจัดเก็บด้วย Preferences DataStore แอปกำหนด DataStore ในชุดซอร์สหลัก ดังนี้

// In app/src/main/kotlin/com/example/myapp/Settings.kt
package com.example.myapp

import android.content.Context
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore

val Context.settingsDataStore by preferencesDataStore(name = "settings")
val THEME_KEY = stringPreferencesKey("theme")

การดำเนินการกับอุปกรณ์จะใช้คำจำกัดความเดียวกัน ดังนี้

// In app/src/backupTest/androidTest/kotlin/com/example/myapp/ThemeActions.kt
package com.example.myapp

import android.content.Context
import androidx.datastore.preferences.core.edit
import androidx.test.backup.BackupDeviceAction
import androidx.test.backup.BackupDeviceActionArgs
import androidx.test.backup.BackupDeviceActionResult
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking

class SeedThemeAction : BackupDeviceAction {
    override val phase = BackupDeviceAction.PHASE_POPULATE

    override fun execute(
        context: Context,
        args: BackupDeviceActionArgs,
    ): BackupDeviceActionResult {
        val theme = args["theme"]
            ?: return BackupDeviceActionResult.failure("Missing theme argument")
        runBlocking {
            context.settingsDataStore.edit { it[THEME_KEY] = theme }
        }
        return BackupDeviceActionResult.success()
    }
}

class VerifyThemeAction : BackupDeviceAction {
    override val phase = BackupDeviceAction.PHASE_VERIFY

    override fun execute(
        context: Context,
        args: BackupDeviceActionArgs,
    ): BackupDeviceActionResult {
        val expected = args["theme"]
        val actual = runBlocking {
            context.settingsDataStore.data.first()[THEME_KEY]
        }
        return if (actual == expected) {
            BackupDeviceActionResult.success()
        } else {
            BackupDeviceActionResult.failure("Expected $expected, found $actual")
        }
    }
}

หากต้องการแสดงข้อมูลกลับไปยังการทดสอบโฮสต์ ให้ส่งแผนที่ไปยังเมธอด success การทดสอบโฮสต์จะอ่านแผนที่จาก BackupActionResult.Success.data

เรียกใช้แต่ละขั้นตอนของโฟลว์

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

package com.example.myapp

import androidx.test.backup.host.BackupActionResult
import androidx.test.backup.host.BackupRestoreConfig
import androidx.test.backup.host.BackupRestoreController
import androidx.test.backup.host.BackupRestoreExtension
import androidx.test.backup.host.BackupTransportMode
import java.nio.file.Path
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.fail
import org.junit.jupiter.api.io.TempDir

const val SEED_THEME = "com.example.myapp.SeedThemeAction"
const val VERIFY_THEME = "com.example.myapp.VerifyThemeAction"

@ExtendWith(BackupRestoreExtension::class)
@BackupRestoreConfig(applicationId = "com.example.myapp")
class ThemeBackupTest {

    @Test
    fun themeSurvivesCloudBackup(
        device: BackupRestoreController,
        @TempDir outputDir: Path,
    ): Unit = runBlocking {
        val args = mapOf("theme" to "dark")
        device.runOnDevice(SEED_THEME, args).assertSuccess()

        device.stopApp()
        val backupFile = device.performBackup(
            BackupTransportMode.CLOUD_ENCRYPTED,
            outputDir,
        )
        device.clearAppData()
        device.performRestore(backupFile)

        device.runOnDevice(VERIFY_THEME, args).assertSuccess()
    }
}

fun BackupActionResult.assertSuccess() {
    if (this is BackupActionResult.Failure) fail(errorMessage)
}

เมื่อการดำเนินการกับอุปกรณ์ล้มเหลว runOnDevice จะแสดง BackupActionResult.Failure แทนที่จะแสดงข้อยกเว้น ดังนั้นให้ตรวจสอบผลลัพธ์ ขั้นตอนอื่นๆ จะแสดงข้อยกเว้นหากล้มเหลว

ทดสอบการโอนระหว่างอุปกรณ์

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

package com.example.myapp

import androidx.test.backup.host.BackupRestoreConfig
import androidx.test.backup.host.BackupRestoreController
import androidx.test.backup.host.BackupRestoreExtension
import androidx.test.backup.host.BackupTransportMode
import androidx.test.backup.host.Device
import java.nio.file.Path
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.io.TempDir

@ExtendWith(BackupRestoreExtension::class)
@BackupRestoreConfig(applicationId = "com.example.myapp")
class ThemeTransferTest {

    @Test
    fun themeTransfersToNewDevice(
        @Device(role = "source") source: BackupRestoreController,
        @Device(role = "target") target: BackupRestoreController,
        @TempDir outputDir: Path,
    ): Unit = runBlocking {
        val args = mapOf("theme" to "dark")
        source.runOnDevice(SEED_THEME, args).assertSuccess()
        source.stopApp()
        val backupFile = source.performBackup(
            BackupTransportMode.DEVICE_TO_DEVICE,
            outputDir,
        )

        target.clearAppData()
        target.performRestore(backupFile)
        target.runOnDevice(VERIFY_THEME, args).assertSuccess()
    }
}

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

เลือกอุปกรณ์

โดยค่าเริ่มต้น เฟรมเวิร์กการทดสอบจะจัดเรียงอุปกรณ์ที่ออนไลน์ตามหมายเลขซีเรียลและกำหนดอุปกรณ์ให้กับพารามิเตอร์ BackupRestoreController ตามตำแหน่ง เช่น พารามิเตอร์แรกของเมธอดทดสอบจะได้รับอุปกรณ์เครื่องแรก และพารามิเตอร์ที่ 2 จะได้รับอุปกรณ์เครื่องที่ 2 หากไม่มีอุปกรณ์สำหรับตำแหน่งหนึ่งๆ พารามิเตอร์จะได้รับอุปกรณ์เครื่องแรก ตำแหน่งจะนับพารามิเตอร์ทั้งหมดของเมธอด ดังนั้นให้ประกาศพารามิเตอร์อุปกรณ์ก่อนพารามิเตอร์อื่นๆ เช่น @TempDir ตัวแปรสภาพแวดล้อม ANDROID_SERIAL จะไม่ส่งผลต่อการกำหนดอุปกรณ์

หากต้องการเลือกอุปกรณ์ ให้ตั้งค่า serial หรือ api ของ @Device หรือตั้งค่าพร็อพเพอร์ตี้ระบบ JVM พร็อพเพอร์ตี้ระบบจะมีลำดับความสำคัญสูงกว่าค่า @Device ตารางต่อไปนี้แสดงพร็อพเพอร์ตี้ระบบที่รองรับ

พร็อพเพอร์ตี้ระบบ คำอธิบาย
androidx.test.backup.device.serial หมายเลขซีเรียลของอุปกรณ์สำหรับพารามิเตอร์อุปกรณ์ทั้งหมด
androidx.test.backup.device.serials รายการที่คั่นด้วยคอมมาของหมายเลขซีเรียล ซึ่งกำหนดให้กับพารามิเตอร์ตามตำแหน่ง
androidx.test.backup.device.serial.{name} หมายเลขซีเรียลสำหรับพารามิเตอร์ที่มีคำอธิบายประกอบ @Device(serial = "{name}")
androidx.test.backup.device.api ระดับ API ของอุปกรณ์สำหรับพารามิเตอร์อุปกรณ์ทั้งหมด
androidx.test.backup.device.apis รายการระดับ API ที่คั่นด้วยคอมมา ซึ่งกำหนดให้กับพารามิเตอร์ตามตำแหน่ง

ส่งพร็อพเพอร์ตี้เหล่านี้ด้วย -D เมื่อเรียกใช้การทดสอบจากบรรทัดคำสั่ง พร็อพเพอร์ตี้จะใช้กับการทดสอบทุกครั้งที่เรียกใช้ ดังนั้นให้ใช้ตัวเลือก --tests เพื่อเรียกใช้เฉพาะการทดสอบที่ต้องใช้พร็อพเพอร์ตี้เหล่านั้น ตัวอย่างเช่น คำสั่งต่อไปนี้จะเรียกใช้ ThemeTransferTest โดยใช้ emulator-5554 เป็นอุปกรณ์ต้นทางและ emulator-5556 เป็นอุปกรณ์เป้าหมาย

./gradlew :app:testDebugBackupTestDefaultTestSuite --tests "com.example.myapp.ThemeTransferTest" -Dandroidx.test.backup.device.serials=emulator-5554,emulator-5556

เก็บข้อมูลแอปไว้ระหว่างการทดสอบ

ก่อนการทดสอบแต่ละครั้ง เฟรมเวิร์กการทดสอบจะล้างข้อมูลของแอปในอุปกรณ์แต่ละเครื่องที่การทดสอบใช้ หากต้องการปิดฟีเจอร์นี้สำหรับคลาสหรือเมธอดทดสอบ ให้ใส่คำอธิบายประกอบ @Isolation(IsolationPolicy.MANUAL)

เขียนการทดสอบใน Java

เมธอด BackupRestoreController เป็นฟังก์ชันระงับของ Kotlin หากคุณเขียน การทดสอบโฮสต์ใน Java ให้ใช้ Variant Async ของแต่ละเมธอด เช่น runBackupRestoreFlowAsync ซึ่งจะแสดงผล ListenableFuture

เรียกใช้การทดสอบการสำรองและกู้คืน

AGP จะสร้างงาน Gradle สำหรับ Variant แต่ละรายการที่ชุดทดสอบจะทดสอบ โดยตั้งชื่อว่า test{Variant}{SuiteName}DefaultTestSuite หากต้องการเรียกใช้ชุดทดสอบ backupTest กับ Variant debug ให้เชื่อมต่ออุปกรณ์และเรียกใช้งานต่อไปนี้

./gradlew :app:testDebugBackupTestDefaultTestSuite

งาน check, test และ connectedCheck จะไม่เรียกใช้ชุดโปรแกรมทดสอบการสำรองและกู้คืน ดังนั้นให้เรียกใช้งานของชุดโปรแกรมทดสอบอย่างชัดเจน

หากต้องการเรียกใช้คลาสหรือเมธอดทดสอบรายการเดียว ให้ใช้ตัวเลือก --tests ดังนี้

./gradlew :app:testDebugBackupTestDefaultTestSuite --tests "com.example.myapp.ThemeBackupTest"

ตรวจสอบรายงานการทดสอบ

หลังจากเรียกใช้การทดสอบเสร็จสมบูรณ์ AGP จะสร้างรายงานการทดสอบ HTML ที่ {module}/build/reports/tests/{taskName}/index.html เช่น app/build/reports/tests/testDebugBackupTestDefaultTestSuite/index.html

ปัญหาและข้อจำกัดที่ทราบ

การทดสอบการสำรองและกู้คืนอัตโนมัติมีปัญหาและข้อจำกัดที่ทราบดังต่อไปนี้

  • ยังไม่รองรับชุดโปรแกรมทดสอบใน Android Studio ตัวแก้ไขโค้ดอาจแสดงข้อผิดพลาดการอ้างอิงที่ไม่ได้รับการแก้ไขในไฟล์ต้นฉบับของชุดโปรแกรมทดสอบ แม้ว่าโปรเจ็กต์จะได้รับการกำหนดค่าอย่างถูกต้องแล้วก็ตาม ให้สร้างและเรียกใช้การทดสอบการสำรองและกู้คืนจากบรรทัดคำสั่งโดยใช้ Gradle แทน
  • การทดสอบจะทำงานเฉพาะในอุปกรณ์และโปรแกรมจำลองที่เชื่อมต่อกับคอมพิวเตอร์สำหรับการพัฒนาซอฟต์แวร์ผ่าน adb ไม่รองรับ Firebase Test Lab
  • การทดสอบจะล้างข้อมูลของแอปและเปลี่ยนการตั้งค่าการสำรองข้อมูลในอุปกรณ์ที่ใช้ เราขอแนะนำให้ใช้อุปกรณ์ทดสอบโดยเฉพาะ

ดูการเปลี่ยนแปลงในแต่ละรุ่นได้ที่ บันทึกประจำรุ่นของการทดสอบการสำรองและกู้คืน