آزمایش خودکار پشتیبان‌گیری و بازیابی

وقتی کاربران دستگاه جدیدی را راه‌اندازی می‌کنند یا برنامه شما را بازنصب می‌کنند، Android می‌تواند داده‌های برنامه‌تان را از نسخه پشتیبان ابری یا انتقال دستگاه‌به‌دستگاه بازیابی کند. اگر قوانین نسخه پشتیبان شما داده‌های مهم را حذف کند، یا برنامه شما نتواند از داده‌هایی که بازیابی می‌کند استفاده کند، کاربران تنظیمات و پیشرفت خود را بدون دیدن خطا ازدست می‌دهند.

آزمایش‌های بازیابی و پشتیبان‌گیری خودکار به شما کمک می‌کنند این مشکلات را قبل‌از انتشار برنامه‌تان شناسایی کنید. این آزمایش‌ها آزمایش‌های JUnit 5 هستند که در ماشین توسعه نرم‌افزار شما اجرا می‌شوند و دستگاه‌های متصل را ازطریق «پل اشکال‌زدایی Android»‏ (adb) کنترل می‌کنند. هر آزمایش داده‌های برنامه را در دستگاهی قرار می‌دهد، از برنامه ازطریق چارچوب پشتیبان‌گیری Android پشتیبان‌گیری و آن را بازیابی می‌کند، و سپس بررسی می‌کند که داده‌ها دست‌نخورده باشند. آزمایش‌ها را به‌عنوان مجموعه آزمایشی افزایه Android Gradle (AGP) در فایل ساخت واحدتان پیکربندی می‌کنید.

روش کار

مجموعه آزمایشی پشتیبان‌گیری و بازیابی دو بخش دارد که باهم کار می‌کنند:

  • آزمایش‌های میزبان آزمایش‌های JUnit 5 هستند که روی ماشین توسعه شما اجرا می‌شوند. آن‌ها از BackupRestoreController برای هر دستگاه استفاده می‌کنند تا داده‌ها را آماده کنند، از برنامه شما پشتیبان‌گیری و آن را بازیابی کنند، و نتایج را بررسی کنند.
  • کنش‌های دستگاه کلاس‌هایی هستند که BackupDeviceAction را پیاده‌سازی می‌کنند. این کدها در فرایند برنامه شما در دستگاه اجرا می‌شوند، بنابراین می‌توانند داده‌ها را ازطریق کد برنامه شما بخوانند و بنویسند. میزبان کنش‌های دستگاه را براساس نام کلاس آزمایش می‌کند.

وقتی مجموعه را اجرا می‌کنید، AGP برنامه شما و فایل APK آزمایشی را که حاوی کنش‌های دستگاه شما است می‌سازد. پیش‌از هر آزمایش، چارچوب آزمایش هر دو APK را روی هر دستگاهی که آزمایش استفاده می‌کند نصب می‌کند و سپس داده‌های برنامه شما را پاک می‌کند.

انواع فضای ذخیره‌سازی داخلی

جدول زیر زیرکلاس‌های StorageDomain را فهرست می‌کند که به شما امکان می‌دهد بدون نوشتن کنش‌های دستگاه، داده‌ها را نمونه‌سازی و درستی‌سنجی کنید:

دامنه فضای ذخیره‌سازی داده
StorageDomain.Preference کلیدی در فایل SharedPreferences.
StorageDomain.Database ردیفی در جدول پایگاه داده SQLite.
StorageDomain.TextFile فایل نوشتاری در فضای ذخیره‌سازی داخلی برنامه‌تان.
StorageDomain.BinaryFile فایل باینری در حافظه داخلی برنامه.

برای آزمایش کردن داده‌های دیگر، مثل فایل‌های DataStore، کنش‌های دستگاه را بنویسید.

وسایل نقلیه

هر پشتیبان‌گیری از مقدار BackupTransportMode استفاده می‌کند. جدول زیر وسایل حمل‌ونقل پشتیبانی‌شده را فهرست می‌کند:

حالت سناریو
LOCAL نسخه پشتیبان به انتقال پشتیبان‌گیری محلی دستگاه. داده‌های پشتیبان‌گیری در دستگاه باقی می‌ماند.
CLOUD_ENCRYPTED نسخه پشتیبان ابری، مثل نسخه‌ای که از دستگاه دارای رمزگذاری سمت کارخواه در «حساب Google» کاربر ذخیره شده است.
CLOUD_UNENCRYPTED نسخه پشتیبان ابری از دستگاهی که رمزگذاری سمت کارخواه ندارد.
DEVICE_TO_DEVICE انتقال دستگاه‌به‌دستگاه، برای مثال ازطریق کابل یا Wi-Fi.

LOCAL در هر دستگاه پشتیبانی‌شده‌ای کار می‌کند. حالت‌های ابری و دستگاه‌به‌دستگاه همان نسخه‌های پشتیبان را ایجاد می‌کنند که کنش پشتیبان‌گیری از داده‌های برنامه در Android Studio ایجاد می‌کند: نسخه پشتیبان به‌جای بارگذاری یا ارسال به دستگاه دیگر، در ماشین توسعه نرم‌افزار شما ذخیره می‌شود. حالت‌های ابری و دستگاه‌به‌دستگاه به خدمات Google Play در دستگاه و ساخت قابل‌اشکال‌زدایی برنامه‌تان نیاز دارند. اگر قوانین پشتیبان‌گیری شما به رمزگذاری سمت کارخواه بستگی دارد، هر دو حالت ابری را آزمایش کنید.

الزامات

برای استفاده از آزمایش پشتیبان‌گیری و بازیابی خودکار، مطمئن شوید محیط شما الزامات زیر را برآورده می‌کند:

  • Gradle نسخه ۹.۶.۰ یا بالاتر.
  • نسخه ۱۷ یا بالاتر JDK.
  • دستگاه یا شبیه‌سازی که Android 12 (سطح میانای برنامه‌سازی کاربردی ۳۱) یا بالاتر دارد و ازطریق adb متصل شده است. برای آزمایش انتقال بین دو دستگاه، دو دستگاه را متصل کنید.

سازگاری

جدول زیر نسخه‌های حداقل و توصیه‌شده را برای آزمایش پشتیبان‌گیری و بازیابی خودکار فهرست می‌کند:

مؤلفه حداقل نسخه نسخه توصیه‌شده
استودیو Android 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 مراجعه کنید.

راه‌اندازی پروژه

برای افزودن مجموعه آزمایشی پشتیبان‌گیری و بازیابی به واحد برنامه، مراحل زیر را تکمیل کنید:

فعال کردن پرچم‌های آزمایشی

در فایل 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"). این ویژگی اختیاری است. اگر آن را حذف کنید، مجموعه انواع testBuildType واحد شما را آزمایش می‌کند، که به‌طور پیش‌فرض debug است. توصیه می‌کنیم گونه قابل‌اشکال‌زدایی را آزمایش کنید زیرا حالت‌های انتقال ابری و دستگاه‌به‌دستگاه به برنامه قابل‌اشکال‌زدایی نیاز دارند.

‫AGP کتابخانه میزبان، androidx.test.backup:backup-host، و JUnit 5 را به آزمایش‌های میزبان اضافه می‌کند. این گزینه کتابخانه دستگاه، androidx.test.backup:backup، را به فایل APK آزمایشی اضافه می‌کند و اجراکننده ابزار دقیق فایل APK آزمایشی را تنظیم می‌کند.

برای افزودن وابستگی‌های دیگر، از بلوک‌های hostJar و testApk مجموعه استفاده کنید. برای مثال، برای استفاده از 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 مجموعه بنویسید. هر کلاس آزمایشی به دو حاشیه‌نویسی نیاز دارد:

  • ‫@ExtendWith(BackupRestoreExtension::class) دستگاه‌های متصل را برای آزمایش‌ها ارائه می‌دهد.
  • @BackupRestoreConfig(applicationId = "...") شناسه برنامه برنامه تحت آزمایش را تنظیم می‌کند. از شناسه برنامه گونه‌ای که آزمایش می‌کنید استفاده کنید، ازجمله هرگونه applicationIdSuffix.

هر روش آزمایش یک پارامتر BackupRestoreController برای هر دستگاهی که استفاده می‌کند اعلام می‌کند.

آزمایش انواع فضای ذخیره‌سازی داخلی

برای آزمایش انواع فضای ذخیره‌سازی داخلی، runBackupRestoreFlow را با داده‌های اولیه، دایرکتوری فایل پشتیبان، و حالت انتقال فراخوانی کنید. روش مراحل زیر را در دستگاه اجرا می‌کند:

  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 مسیرهای نسبی را درمقابل filesDir برنامه‌تان حل می‌کنند.
  • Database ردیف را با SQL می‌نویسد و اگر جدول وجود نداشته باشد، جدول را با ستون‌های TEXT ایجاد می‌کند. اگر برنامه‌تان از Room استفاده می‌کند، توصیه می‌کنیم محتوای پایگاه داده را با کنش‌های دستگاه که از DAO شما استفاده می‌کنند آزمایش کنید تا پایگاه داده طرح‌واره‌ای را داشته باشد که Room انتظار دارد.

نوشتن کنش‌های دستگاه

برای کاشتن یا درستی‌سنجی داده‌هایی که انواع فضای ذخیره‌سازی داخلی پوشش نمی‌دهند، کنش‌های دستگاه را در مجموعه منبع androidTest مجموعه بنویسید. کنش دستگاه BackupDeviceAction را پیاده‌سازی می‌کند و دو عضو را ملغی می‌کند:

  • برای کنشی که داده‌ها را می‌کارد، phase را روی BackupDeviceAction.PHASE_POPULATE تنظیم کنید، یا برای کنشی که داده‌ها را بررسی می‌کند، روی BackupDeviceAction.PHASE_VERIFY تنظیم کنید.
  • execute را پیاده‌سازی کنید تا کنش را با Context برنامه و استدلال‌های آزمون میزبان اجرا کنید. نتیجه ایجادشده با روش کارخانه‌ای BackupDeviceActionResult.success یا BackupDeviceActionResult.failure را برگردانید و پیام خطا را به 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 برمی‌گرداند، بنابراین نتیجه را بررسی کنید. مراحل دیگر درصورت عدم موفقیت استثنایی را ایجاد می‌کنند.

آزمایش انتقال بین دستگاه‌ها

برای آزمایش انتقال بین دو دستگاه، یک پارامتر 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 برچسبی است که خواندن آزمایش را آسان‌تر می‌کند. این تنظیم بر دستگاهی که پارامتر را دریافت می‌کند تأثیری ندارد. اگر فقط یک دستگاه متصل باشد، هر دو پارامتر از آن دستگاه استفاده می‌کنند و آزمایش انتقال را در یک دستگاه شبیه‌سازی می‌کند. پاک کردن داده‌های مقصد تضمین می‌کند که داده‌های بازیابی‌شده از نسخه پشتیبان می‌آید.

انتخاب دستگاه

به‌طور پیش‌فرض، چارچوب آزمایشی دستگاه‌های آنلاین را براساس شماره سریال مرتب می‌کند و آن‌ها را براساس موقعیت به پارامترهای BackupRestoreController اختصاص می‌دهد. برای مثال، پارامتر اول روش آزمایش دستگاه اول را دریافت می‌کند و پارامتر دوم دستگاه دوم را دریافت می‌کند. اگر دستگاهی برای موقعیت وجود نداشته باشد، پارامتر اولین دستگاه را دریافت می‌کند. موقعیت‌ها همه پارامترهای روش را شمارش می‌کنند، بنابراین پارامترهای دستگاه را قبل‌از پارامترهای دیگر، مثل @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 سطح میانای برنامه‌سازی کاربردی دستگاه برای همه پارامترهای دستگاه.
androidx.test.backup.device.apis فهرست جداشده با کاما از سطوح میانای برنامه‌سازی کاربردی که براساس موقعیت به پارامترها اختصاص داده شده است.

وقتی آزمایش‌ها را از خط فرمان اجرا می‌کنید، این ویژگی‌ها را با -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 هستند. اگر آزمایش‌های میزبان را در جاوا می‌نویسید، از گونه Async هر روش استفاده کنید، مثل runBackupRestoreFlowAsync، که ListenableFuture را برمی‌گرداند.

اجرای آزمایش‌های پشتیبان‌گیری و بازیابی

«افزایه Gradle اندروید» برای هر گونه‌ای که مجموعه آزمایش می‌کند، وظیفه Gradle ایجاد می‌کند که نام آن test{Variant}{SuiteName}DefaultTestSuite است. برای اجرای مجموعه backupTest درمقابل گونه 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 پشتیبانی نمی‌شود.
  • آزمایش‌ها داده‌های برنامه شما را پاک می‌کنند و تنظیمات پشتیبان‌گیری را در دستگاه‌هایی که استفاده می‌کنند تغییر می‌دهند. توصیه می‌کنیم از دستگاه‌های آزمایش اختصاصی استفاده کنید.

برای تغییرات هر نسخه پخش، یادداشت‌های نسخه پخش آزمایش پشتیبان‌گیری و بازیابی را ببینید.