Saat pengguna menyiapkan perangkat baru atau menginstal ulang aplikasi Anda, Android dapat memulihkan data aplikasi Anda dari pencadangan cloud atau transfer antarperangkat. Jika aturan pencadangan Anda mengabaikan data penting, atau aplikasi Anda tidak dapat menggunakan data yang dipulihkan, pengguna akan kehilangan setelan dan progresnya tanpa melihat error.
Pengujian pencadangan dan pemulihan otomatis membantu Anda mendeteksi masalah ini sebelum merilis aplikasi. Pengujian ini adalah pengujian JUnit 5 yang berjalan di mesin pengembangan dan mengontrol perangkat terhubung melalui Android Debug Bridge (adb). Setiap pengujian menyisipkan data aplikasi di perangkat, mencadangkan dan memulihkan aplikasi melalui framework pencadangan Android, lalu memeriksa apakah data tersebut utuh. Anda mengonfigurasi pengujian sebagai suite pengujian plugin Android Gradle (AGP) dalam file build modul.
Cara kerjanya
Suite pengujian pencadangan dan pemulihan memiliki dua bagian yang bekerja sama:
- Pengujian host adalah pengujian JUnit 5 yang berjalan di mesin pengembangan Anda. Mereka
menggunakan
BackupRestoreControlleruntuk setiap perangkat guna menyisipkan data, mencadangkan dan memulihkan aplikasi, serta memeriksa hasilnya. - Tindakan perangkat adalah class yang mengimplementasikan
BackupDeviceAction. Pengujian ini berjalan dalam proses aplikasi Anda di perangkat, sehingga dapat membaca dan menulis data melalui kode aplikasi Anda sendiri. Pengujian host memanggil tindakan perangkat berdasarkan nama class.
Saat Anda menjalankan suite, AGP akan mem-build aplikasi dan APK pengujian yang berisi tindakan perangkat Anda. Framework pengujian menginstal kedua APK di setiap perangkat yang digunakan pengujian dan menghapus data aplikasi Anda sebelum setiap pengujian.
Jenis penyimpanan bawaan
Tabel berikut mencantumkan subclass StorageDomain yang
memungkinkan Anda menyisipkan dan memverifikasi data tanpa menulis tindakan perangkat:
| Domain penyimpanan | Data |
|---|---|
StorageDomain.Preference |
Kunci dalam file SharedPreferences. |
StorageDomain.Database |
Baris dalam tabel database SQLite. |
StorageDomain.TextFile |
File teks di penyimpanan internal aplikasi Anda. |
StorageDomain.BinaryFile |
File biner di penyimpanan internal aplikasi Anda. |
Untuk menguji data lain, seperti file DataStore, tulis tindakan perangkat.
Moda transportasi
Setiap cadangan menggunakan nilai BackupTransportMode. Tabel berikut mencantumkan mode transportasi yang didukung:
| Mode | Skenario |
|---|---|
LOCAL |
Pencadangan ke transpor pencadangan lokal perangkat. Data cadangan tetap berada di perangkat. |
CLOUD_ENCRYPTED |
Cadangan cloud, seperti yang disimpan ke Akun Google pengguna dari perangkat dengan enkripsi sisi klien. |
CLOUD_UNENCRYPTED |
Cadangan cloud dari perangkat yang tidak memiliki enkripsi sisi klien. |
DEVICE_TO_DEVICE |
Transfer antarperangkat, misalnya melalui kabel atau Wi-Fi. |
LOCAL berfungsi di perangkat apa pun yang didukung. Mode cloud dan perangkat ke perangkat
membuat cadangan yang sama dengan tindakan Backup App Data di Android Studio:
cadangan disimpan ke mesin pengembangan, bukan diupload atau
dikirim ke perangkat lain. Mode cloud dan perangkat ke perangkat memerlukan layanan Google Play
di perangkat dan build aplikasi yang dapat di-debug. Jika aturan pencadangan Anda
bergantung pada enkripsi sisi klien, uji kedua mode cloud.
Persyaratan
Untuk menggunakan pengujian pencadangan dan pemulihan otomatis, pastikan lingkungan Anda memenuhi persyaratan berikut:
- Gradle versi 9.6.0 atau yang lebih tinggi.
- JDK versi 17 atau yang lebih baru.
- Perangkat atau emulator yang menjalankan Android 12 (level API 31) atau yang lebih tinggi yang terhubung melalui adb:
- Perangkat atau emulator di level API 36.1 atau yang lebih tinggi memerlukan layanan Google Play versi 26.33.30 atau yang lebih tinggi.
- Untuk menguji transfer antara dua perangkat, hubungkan dua perangkat.
Kompatibilitas
Tabel berikut mencantumkan versi minimum dan yang direkomendasikan untuk pengujian pencadangan dan pemulihan otomatis:
| Komponen | Versi minimum | Versi yang direkomendasikan |
|---|---|---|
| Android Studio | Rabbit 2 Canary 1 | Rabbit 2 Canary 4 atau yang lebih tinggi |
| Plugin Android Gradle (AGP) | 9.5.0-alpha06 | 9.5.0-alpha09 atau yang lebih tinggi |
androidx.test.backup library |
1.0.0-alpha01 | 1.0.0-alpha03 atau yang lebih tinggi |
Setiap versi pratinjau AGP memerlukan versi pratinjau Android Studio yang sesuai. Untuk mengetahui informasi selengkapnya, lihat Pratinjau AGP.
Menyiapkan project
Untuk menambahkan suite pengujian pencadangan dan pemulihan ke modul aplikasi, selesaikan langkah-langkah berikut:
Mengaktifkan tanda eksperimental
Dalam file gradle.properties project Anda, aktifkan suite pengujian dan pengujian
cadangan:
android.experimental.testSuiteSupport=true
android.experimental.enableBackupTest=true
Mendeklarasikan suite pengujian
Dalam file build.gradle.kts modul aplikasi, deklarasikan suite pengujian pencadangan di
blok testOptions:
android {
testOptions {
backupTests {
create("backupTest") {
backupTestLibraryVersion = "1.0.0-alpha03"
}
}
}
}
Nama suite, backupTest dalam contoh ini, menentukan direktori set sumber
dan nama tugas Gradle. Anda dapat menyesuaikan suite dengan
properti opsional berikut:
- Gunakan
backupTestLibraryVersionuntuk menetapkan versi libraryandroidx.test.backupyang ditambahkan AGP ke suite, seperti"1.0.0-alpha03". Properti ini bersifat opsional. Jika Anda menghilangkannya, AGP akan kembali ke versi library default berdasarkan versi AGP. Contoh di halaman ini memerlukan versi 1.0.0-alpha03 atau yang lebih tinggi. - Gunakan
targetVariantsuntuk menentukan varian build yang diuji suite, sepertitargetVariants.add("demoDebug"). Properti ini bersifat opsional. Jika Anda menghilangkannya, suite akan menguji variantestBuildTypemodul Anda, yang secara default adalahdebug. Sebaiknya uji varian yang dapat di-debug karena mode transportasi cloud dan perangkat ke perangkat memerlukan aplikasi yang dapat di-debug.
AGP menambahkan library host, androidx.test.backup:backup-host, dan JUnit 5 ke
pengujian host. Tindakan ini akan menambahkan library perangkat, androidx.test.backup:backup, ke
APK pengujian dan menetapkan runner instrumentasi APK pengujian.
Untuk menambahkan dependensi lain, gunakan blok hostJar dan testApk dari suite.
Misalnya, untuk menggunakan Truth dalam pengujian host, tambahkan ke blok
hostJar:
create("backupTest") {
hostJar {
dependencies {
implementation("com.google.truth:truth:1.4.2")
}
}
}
Membuat set sumber
Buat direktori set sumber yang cocok dengan nama suite:
- Tempatkan pengujian host di
src/{suiteName}/test/kotlin/. - Tempatkan tindakan perangkat di
src/{suiteName}/androidTest/kotlin/.
Misalnya, suite bernama backupTest menggunakan struktur direktori berikut:
app/src/backupTest/
├── androidTest/
│ └── kotlin/com/example/myapp/ThemeActions.kt
└── test/
└── kotlin/com/example/myapp/SettingsBackupTest.kt
Memeriksa konfigurasi cadangan Anda
Menguji pencadangan dan pemulihan data yang disertakan dalam konfigurasi pencadangan aplikasi Anda. Pastikan pencadangan diaktifkan untuk aplikasi Anda dan aturan pencadangan menyertakan data yang Anda uji.
Menulis pengujian pencadangan dan pemulihan
Tulis pengujian host di set sumber test suite. Anotasikan setiap class pengujian dengan
@ExtendWith(BackupRestoreExtension::class), yang menyediakan perangkat terhubung
ke pengujian. Pengujian dijalankan terhadap varian aplikasi yang ditargetkan oleh suite, sehingga
Anda tidak perlu menetapkan ID aplikasinya.
Setiap metode pengujian mendeklarasikan parameter BackupRestoreController untuk setiap perangkat
yang digunakannya.
Menguji jenis penyimpanan bawaan
Untuk menguji jenis penyimpanan bawaan, panggil runBackupRestoreFlow dengan
data yang akan di-seed, direktori untuk file cadangan, dan mode transpor. Metode
ini menjalankan langkah-langkah berikut di perangkat:
- Menyemai setiap domain penyimpanan.
- Menghentikan aplikasi.
- Mencadangkan aplikasi.
- Menghapus data aplikasi.
- Memulihkan cadangan.
- Memverifikasi bahwa setiap domain penyimpanan memiliki nilai awal.
Jika sebuah langkah gagal, metode akan menampilkan pengecualian, yang akan menggagalkan pengujian. Contoh
berikut menguji kunci SharedPreferences, baris SQLite, dan
file internal menggunakan transpor pencadangan lokal:
package com.example.myapp
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)
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,
)
}
}
Perhatikan hal-hal berikut saat Anda menentukan domain penyimpanan:
Preferencemengambil nama fileSharedPreferencestanpa ekstensi.xml.TextFiledanBinaryFileme-resolve jalur relatif terhadapfilesDiraplikasi Anda.Databasemenulis baris dengan SQL, dan membuat tabel dengan kolomTEXTjika tabel tidak ada. Jika aplikasi Anda menggunakan Room, sebaiknya uji konten database dengan tindakan perangkat yang menggunakan DAO Anda sehingga database memiliki skema yang diharapkan Room.
Menulis tindakan perangkat
Untuk menyisipkan atau memverifikasi data yang tidak tercakup dalam jenis penyimpanan bawaan, tulis
tindakan perangkat di set sumber androidTest suite. Tindakan perangkat
mengimplementasikan BackupDeviceAction dan mengganti dua anggota:
- Tetapkan
phasekeBackupDeviceAction.PHASE_POPULATEuntuk tindakan yang menyisipkan data, atauBackupDeviceAction.PHASE_VERIFYuntuk tindakan yang memeriksa data. - Terapkan
executeuntuk menjalankan tindakan denganContextaplikasi Anda dan argumen dari pengujian host. Tampilkan hasil yang dibuat dengan metode factoryBackupDeviceActionResult.successatauBackupDeviceActionResult.failure, dan teruskan pesan error kefailure.
Metode execute berjalan dalam proses aplikasi Anda di thread latar belakang, sehingga dapat memblokir hingga operasi baca dan tulis selesai.
Contoh berikut menyisipkan dan memverifikasi setelan tema yang disimpan aplikasi dengan Preferences DataStore. Aplikasi menentukan DataStore dalam set sumber utamanya:
// 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")
Tindakan perangkat menggunakan definisi yang sama:
// 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")
}
}
}
Untuk menampilkan data ke pengujian host, teruskan peta ke metode success. Pengujian host
membaca peta dari BackupActionResult.Success.data.
Menjalankan setiap langkah alur
Untuk menggunakan tindakan perangkat, atau untuk menyesuaikan alur, panggil setiap langkah sendiri. Pengujian host berikut menjalankan tindakan perangkat dari bagian sebelumnya seputar pencadangan dan pemulihan cloud:
package com.example.myapp
import androidx.test.backup.host.BackupActionResult
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)
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)
}
Jika tindakan perangkat gagal, runOnDevice akan menampilkan
BackupActionResult.Failure, bukan menampilkan pengecualian,
jadi periksa hasilnya. Langkah-langkah lainnya akan menampilkan pengecualian jika gagal.
Menguji transfer antarperangkat
Untuk menguji transfer antara dua perangkat, deklarasikan parameter BackupRestoreController
untuk setiap perangkat. Cadangkan aplikasi di perangkat sumber, lalu
pulihkan file cadangan di perangkat target. Contoh berikut menggunakan kembali
konstanta dan helper assertSuccess dari contoh sebelumnya:
package com.example.myapp
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)
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()
}
}
Nilai role dari @Device memungkinkan Anda
memilih perangkat untuk setiap parameter saat menjalankan pengujian. Jika hanya satu perangkat yang terhubung, kedua parameter akan menggunakan perangkat tersebut, dan pengujian akan menyimulasikan transfer pada satu perangkat. Menghapus data target akan memastikan bahwa data yang dipulihkan berasal dari cadangan.
Pilih perangkat
Secara default, framework pengujian mengurutkan perangkat online berdasarkan nomor seri dan menetapkannya ke parameter BackupRestoreController dari setiap pengujian secara berurutan.
Jika pengujian memiliki lebih banyak parameter perangkat daripada jumlah perangkat, parameter tambahan akan menggunakan perangkat pertama. Variabel lingkungan ANDROID_SERIAL
tidak memengaruhi penetapan perangkat.
Untuk memilih perangkat tanpa memasukkan nomor seri dalam pengujian, berikan peran pada setiap parameter perangkat dengan @Device(role = "..."). Kemudian, saat Anda menjalankan pengujian,
ikat setiap peran ke perangkat dengan
properti sistem androidx.test.backup.device.serial.{role}. Misalnya, perintah berikut menjalankan suite dengan emulator-5554 sebagai perangkat sumber dan
emulator-5556 sebagai perangkat target:
./gradlew :app:testDebugBackupTestDefaultTestSuite -Dandroidx.test.backup.device.serial.source=emulator-5554 -Dandroidx.test.backup.device.serial.target=emulator-5556Binding hanya berlaku untuk parameter dengan peran tersebut. Parameter lainnya mendapatkan perangkat yang tersisa.
Anda juga dapat memilih perangkat dengan nilai serial dan api dari @Device, atau
dengan properti sistem berikut, yang lebih diprioritaskan daripada nilai
@Device:
| Properti sistem | Deskripsi |
|---|---|
androidx.test.backup.device.serial.{role} |
Nomor seri perangkat untuk parameter yang dianotasi dengan @Device(role = "{role}"). Kebijakan ini lebih diprioritaskan daripada serials dan serial. |
androidx.test.backup.device.serials |
Daftar nomor seri yang dipisahkan koma, yang ditetapkan ke parameter perangkat secara berurutan. |
androidx.test.backup.device.serial |
Nomor seri perangkat untuk parameter perangkat yang tidak tercakup dalam serials. |
androidx.test.backup.device.apis |
Daftar level API yang dipisahkan koma, yang ditetapkan ke parameter perangkat secara berurutan. |
androidx.test.backup.device.api |
Level API perangkat untuk parameter perangkat yang tidak tercakup dalam apis. |
Teruskan properti ini dengan -D dengan cara yang sama. Properti serial, serials,
api, dan apis berlaku untuk setiap pengujian yang berjalan, jadi gunakan
opsi --tests untuk hanya menjalankan pengujian yang memerlukannya.
Menguji Pemulihan Kredensial
Jika aplikasi Anda menggunakan Restore Credentials, uji apakah
kunci pemulihannya bertahan setelah pencadangan dan pemulihan. Mode cloud dan perangkat ke perangkat
mencadangkan kunci dengan data aplikasi Anda, tetapi LOCAL tidak.
Tulis tindakan perangkat yang membuat kunci dan mendapatkannya dengan Credential Manager. Tindakan
pembuatan menampilkan ID kredensial kunci, sehingga tindakan verifikasi dapat
memeriksa apakah pemulihan mengembalikan kunci yang sama. Dalam contoh ini,
createRequestJson dan getRequestJson adalah string JSON permintaan yang diteruskan
aplikasi Anda ke Credential Manager:
// In app/src/backupTest/androidTest/kotlin/com/example/myapp/RestoreKeyActions.kt
package com.example.myapp
import android.content.Context
import androidx.credentials.CreateRestoreCredentialRequest
import androidx.credentials.CreateRestoreCredentialResponse
import androidx.credentials.CredentialManager
import androidx.credentials.GetCredentialRequest
import androidx.credentials.GetRestoreCredentialOption
import androidx.credentials.RestoreCredential
import androidx.test.backup.BackupDeviceAction
import androidx.test.backup.BackupDeviceActionArgs
import androidx.test.backup.BackupDeviceActionResult
import kotlinx.coroutines.runBlocking
import org.json.JSONObject
class CreateRestoreKeyAction : BackupDeviceAction {
override val phase = BackupDeviceAction.PHASE_POPULATE
override fun execute(
context: Context,
args: BackupDeviceActionArgs,
): BackupDeviceActionResult {
val request = CreateRestoreCredentialRequest(createRequestJson)
val response = runBlocking {
CredentialManager.create(context).createCredential(context, request)
} as CreateRestoreCredentialResponse
val credentialId = JSONObject(response.responseJson).getString("id")
return BackupDeviceActionResult.success(mapOf("credential_id" to credentialId))
}
}
class VerifyRestoreKeyAction : BackupDeviceAction {
override val phase = BackupDeviceAction.PHASE_VERIFY
override fun execute(
context: Context,
args: BackupDeviceActionArgs,
): BackupDeviceActionResult {
val option = GetRestoreCredentialOption(getRequestJson)
val response = runBlocking {
CredentialManager.create(context)
.getCredential(context, GetCredentialRequest(listOf(option)))
}
val credential = response.credential as RestoreCredential
val credentialId = JSONObject(credential.authenticationResponseJson).getString("id")
val expected = args["credential_id"]
return if (credentialId == expected) {
BackupDeviceActionResult.success()
} else {
BackupDeviceActionResult.failure("Expected key $expected, found $credentialId")
}
}
}
Pengujian host berikut membuat kunci di perangkat sumber, memulihkannya di
perangkat target, dan memeriksanya di sana. Fungsi ini menggunakan helper assertSuccess dari
Menjalankan setiap langkah flow:
package com.example.myapp
import androidx.test.backup.host.BackupActionResult
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
const val CREATE_RESTORE_KEY = "com.example.myapp.CreateRestoreKeyAction"
const val VERIFY_RESTORE_KEY = "com.example.myapp.VerifyRestoreKeyAction"
@ExtendWith(BackupRestoreExtension::class)
class RestoreKeyTest {
@Test
fun restoreKeyTransfersToNewDevice(
@Device(role = "source") source: BackupRestoreController,
@Device(role = "target") target: BackupRestoreController,
@TempDir outputDir: Path,
): Unit = runBlocking {
val created = source.runOnDevice(CREATE_RESTORE_KEY)
created.assertSuccess()
val credentialId =
(created as BackupActionResult.Success).data.getValue("credential_id")
source.stopApp()
val backupFile = source.performBackup(
BackupTransportMode.DEVICE_TO_DEVICE,
outputDir,
)
// Also deletes any restore key on the target.
target.clearAppData()
target.performRestore(backupFile)
target.runOnDevice(VERIFY_RESTORE_KEY, mapOf("credential_id" to credentialId))
.assertSuccess()
}
}
Untuk membuat kunci dengan isCloudBackupEnabled yang ditetapkan ke true, yaitu setelan default, perangkat sumber memerlukan Akun Google dengan pencadangan yang diaktifkan dan kunci layar.
Jika tidak, Pengelola Kredensial akan menampilkan
E2eeUnavailableException.
Tidak seperti pemulihan cloud di perangkat baru, mode cloud tidak memerlukan Akun Google yang sama atau kunci layar perangkat sumber, dan mode ini memulihkan kunci yang dibuat dengan isCloudBackupEnabled yang ditetapkan ke false.
Menyimpan data aplikasi di antara pengujian
Sebelum setiap pengujian, framework pengujian akan menghapus data aplikasi Anda di setiap perangkat yang digunakan pengujian. Untuk menonaktifkan ini untuk class atau metode pengujian, anotasikan dengan
@Isolation(IsolationPolicy.MANUAL).
Menulis pengujian di Java
Metode BackupRestoreController adalah fungsi penangguhan Kotlin. Jika Anda menulis
pengujian host di Java, gunakan varian Async dari setiap metode, seperti
runBackupRestoreFlowAsync, yang menampilkan ListenableFuture.
Menjalankan pengujian pencadangan dan pemulihan
AGP membuat tugas Gradle untuk setiap varian yang diuji oleh suite, yang diberi nama
test{Variant}{SuiteName}DefaultTestSuite. Untuk menjalankan suite backupTest
terhadap varian debug, hubungkan perangkat Anda dan jalankan tugas:
./gradlew :app:testDebugBackupTestDefaultTestSuiteTugas check, test, dan connectedCheck tidak menjalankan suite pengujian pencadangan dan pemulihan, jadi jalankan tugas suite secara eksplisit.
Untuk menjalankan satu class atau metode pengujian, gunakan
opsi --tests:
./gradlew :app:testDebugBackupTestDefaultTestSuite --tests "com.example.myapp.ThemeBackupTest"Memeriksa laporan pengujian
Setelah pengujian selesai, AGP akan membuat laporan pengujian HTML di
{module}/build/reports/tests/{taskName}/index.html, seperti
app/build/reports/tests/testDebugBackupTestDefaultTestSuite/index.html.
Memecahkan masalah pemulihan yang gagal
Pemulihan cloud atau perangkat ke perangkat gagal dengan pesan error dalam kasus berikut:
- Layanan Google Play melewati aplikasi Anda, misalnya karena ID aplikasinya
dimulai dengan
com.google.ataucom.android., cadangannya kosong, atau menetapkanandroid:allowBackup="false". Untuk menguji aplikasi dengan ID aplikasi tersebut, gunakan modeLOCAL. - Versi layanan Google Play lebih rendah dari 26.33.30 di perangkat atau emulator yang menjalankan level API 36.1 atau yang lebih tinggi. Update layanan Google Play melalui Google Play Store di perangkat, atau gunakan image sistem yang dilengkapi dengan versi 26.33.30 atau yang lebih tinggi.
Masalah umum dan batasan
Pengujian pencadangan dan pemulihan otomatis memiliki masalah umum dan batasan berikut:
- Dukungan Android Studio untuk suite pengujian belum tersedia. Editor kode mungkin menampilkan error referensi yang belum terselesaikan dalam file sumber suite pengujian, meskipun project Anda dikonfigurasi dengan benar. Sebagai gantinya, build dan jalankan pengujian pencadangan dan pemulihan dari command line menggunakan Gradle.
- Pengujian hanya berjalan di perangkat dan emulator yang terhubung ke mesin pengembangan Anda melalui adb. Firebase Test Lab tidak didukung.
- Pengujian akan menghapus data aplikasi Anda dan mengubah setelan pencadangan di perangkat yang digunakan. Sebaiknya gunakan perangkat pengujian khusus.
Untuk mengetahui perubahan di setiap rilis, lihat catatan rilis pengujian pencadangan dan pemulihan.