الگوهای رایج

می‌توانید برنامه Compose خود را با رویکردها و الگوهای به خوبی تثبیت شده آزمایش کنید.

تست به صورت مجزا

ComposeTestRule به شما امکان می دهد یک فعالیت را شروع کنید که هر ترکیبی را نمایش می دهد: برنامه کامل، یک صفحه یا یک عنصر کوچک. همچنین این یک تمرین خوب است که بررسی کنید که قطعات کامپوزیشن شما به درستی کپسوله شده اند و به طور مستقل کار می کنند و امکان تست رابط کاربری آسان تر و متمرکزتر را فراهم می کند.

این بدان معنا نیست که شما فقط باید تست های واحد UI ایجاد کنید. تست‌های UI که بخش‌های بزرگ‌تری از UI شما را شامل می‌شود نیز بسیار مهم هستند.

پس از تنظیم محتوای خود به فعالیت و منابع دسترسی پیدا کنید

اغلب اوقات شما نیاز دارید که محتوای تحت آزمایش را با استفاده از composeTestRule.setContent تنظیم کنید و همچنین باید به منابع فعالیت دسترسی داشته باشید، به عنوان مثال برای تأیید اینکه متن نمایش داده شده با یک منبع رشته مطابقت دارد. با این حال، اگر اکتیویتی قبلاً آن را فراخوانی کرده باشد، نمی‌توانید setContent روی قانون ایجاد شده با createAndroidComposeRule() فراخوانی کنید.

یک الگوی رایج برای رسیدن به این هدف، ایجاد AndroidComposeTestRule با استفاده از یک فعالیت خالی مانند ComponentActivity است.

class MyComposeTest {

    @get:Rule
    val composeTestRule = createAndroidComposeRule<ComponentActivity>()

    @Test
    fun myTest() {
        // Start the app
        composeTestRule.setContent {
            MyAppTheme {
                MainScreen(uiState = exampleUiState, /*...*/)
            }
        }
        val continueLabel = composeTestRule.activity.getString(R.string.next)
        composeTestRule.onNodeWithText(continueLabel).performClick()
    }
}

توجه داشته باشید که ComponentActivity باید به فایل AndroidManifest.xml برنامه شما اضافه شود. با افزودن این وابستگی به ماژول خود، آن را فعال کنید:

debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")

ویژگی های معنایی سفارشی

شما می توانید ویژگی های معنایی سفارشی ایجاد کنید تا اطلاعات را در معرض آزمایش قرار دهید. برای انجام این کار، یک SemanticsPropertyKey جدید تعریف کرده و با استفاده از SemanticsPropertyReceiver در دسترس قرار دهید.

// Creates a semantics property of type Long.
val PickedDateKey = SemanticsPropertyKey<Long>("PickedDate")
var SemanticsPropertyReceiver.pickedDate by PickedDateKey

حال از آن ویژگی در تعدیل کننده semantics استفاده کنید:

val datePickerValue by remember { mutableStateOf(0L) }
MyCustomDatePicker(
    modifier = Modifier.semantics { pickedDate = datePickerValue }
)

از تست‌ها، از SemanticsMatcher.expectValue برای اثبات مقدار ویژگی استفاده کنید:

composeTestRule
    .onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
    .assertExists()

بازیابی حالت را تأیید کنید

بررسی کنید که وقتی فعالیت یا فرآیند دوباره ایجاد می شود، وضعیت عناصر Compose شما به درستی بازیابی شده است. چنین بررسی هایی را بدون اتکا به فعالیت های تفریحی با کلاس StateRestorationTester انجام دهید.

این کلاس به شما امکان می دهد بازسازی یک کامپوزیشن را شبیه سازی کنید. به ویژه برای تأیید اجرای rememberSaveable مفید است.


class MyStateRestorationTests {

    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun onRecreation_stateIsRestored() {
        val restorationTester = StateRestorationTester(composeTestRule)

        restorationTester.setContent { MainScreen() }

        // TODO: Run actions that modify the state

        // Trigger a recreation
        restorationTester.emulateSavedInstanceStateRestore()

        // TODO: Verify that state has been correctly restored.
    }
}

تنظیمات مختلف دستگاه را تست کنید

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

DeviceConfigurationOverride یک API فقط آزمایشی است که به شما امکان می دهد پیکربندی های مختلف دستگاه را به روشی محلی برای محتوای @Composable تحت آزمایش شبیه سازی کنید.

شیء همراه DeviceConfigurationOverride دارای توابع پسوند زیر است که ویژگی های پیکربندی سطح دستگاه را نادیده می گیرد:

برای اعمال یک نادیده گرفتن خاص، محتوای تحت آزمایش را در یک فراخوانی به تابع سطح بالای DeviceConfigurationOverride() بپیچید و لغو را ارسال کنید تا به عنوان یک پارامتر اعمال شود.

به عنوان مثال، کد زیر از DeviceConfigurationOverride.ForcedSize() برای تغییر چگالی به صورت محلی استفاده می کند، و MyScreen را مجبور می کند در یک پنجره افقی بزرگ رندر شود، حتی اگر دستگاهی که آزمایش روی آن اجرا می شود مستقیماً از آن اندازه پنجره پشتیبانی نمی کند. :

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp))
    ) {
        MyScreen() // will be rendered in the space for 1280dp by 800dp without clipping
    }
}

برای اعمال چند نادیده گرفتن با هم، از DeviceConfigurationOverride.then() استفاده کنید:

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.FontScale(1.5f) then
            DeviceConfigurationOverride.FontWeightAdjustment(200)
    ) {
        Text(text = "text with increased scale and weight")
    }
}

منابع اضافی

  • آزمایش برنامه ها در اندروید : صفحه اصلی آزمایش اندروید نمای وسیع تری از اصول و تکنیک های آزمایش ارائه می دهد.
  • اصول آزمایش : درباره مفاهیم اصلی آزمایش یک برنامه اندروید بیشتر بدانید.
  • تست های محلی : می توانید برخی از آزمایش ها را به صورت محلی، در ایستگاه کاری خود اجرا کنید.
  • تست‌های ابزاری : اجرای تست‌های ابزاری نیز تمرین خوبی است. یعنی تست هایی که مستقیماً روی دستگاه اجرا می شوند.
  • ادغام مداوم : ادغام مداوم به شما امکان می دهد آزمایشات خود را در خط لوله استقرار خود ادغام کنید.
  • اندازه‌های مختلف صفحه نمایش را آزمایش کنید : با دستگاه‌های زیادی که در دسترس کاربران است، باید اندازه‌های مختلف صفحه نمایش را آزمایش کنید.
  • اسپرسو : در حالی که برای UI های مبتنی بر View در نظر گرفته شده است، دانش اسپرسو همچنان می تواند برای برخی از جنبه های تست Compose مفید باشد.