میتوانید برنامه «نگارش» خود را با رویکردها و الگوهای تثبیتشده آزمایش کنید.
آزمایش در انزوا
ComposeTestRule به شما امکان میدهد فعالیتی را شروع کنید که هر عنصر ترکیبی را نمایش میدهد:
کل برنامه، یک صفحه، یا یک عنصر کوچک. همچنین بررسی اینکه عناصر ترکیبی شما بهدرستی کپسوله شدهاند و بهطور مستقل کار میکنند، روشی خوب است که امکان آزمایش رابط کاربری آسانتر و متمرکزتری را فراهم میکند.
این بدان معنا نیست که شما باید فقط آزمونهای واحد واسط کاربر ایجاد کنید. آزمایشهای واسط کاربر که بخشهای بزرگتری از واسط کاربر شما را دربرمیگیرد نیز بسیار مهم است.
پساز تنظیم محتوای خودتان، به فعالیت و منابع دسترسی پیدا کنید
اغلب اوقات باید محتوای تحت آزمایش را بااستفاده از
composeTestRule.setContent تنظیم کنید و همچنین باید به منابع فعالیت دسترسی داشته باشید، برای
مثال برای تأیید اینکه نوشتار نمایشدادهشده با منبع رشتهای مطابقت دارد. بااینحال، اگر
فعالیت ازقبل با تماس میگیرد، نمی
توانید در قانونی که با createAndroidComposeRule() ساخته شده است با setContent تماس بگیرید.
الگوی رایج برای دستیابی به این هدف ایجاد 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.
}
}
پیکربندیهای مختلف دستگاه را آزمایش کنید
برنامههای Android باید با شرایط متغیر زیادی سازگار شوند: اندازههای پنجره، زبانها،
اندازههای قلم، زمینههای تیره و روشن، و غیره. بیشتر این شرایط از مقادیر سطح دستگاه که توسط کاربر کنترل میشود و با نمونه Configuration فعلی آشکار میشود مشتق شدهاند. آزمایش پیکربندیهای مختلف بهطور مستقیم در آزمایش دشوار است زیرا آزمایش باید ویژگیهای سطح دستگاه را پیکربندی کند.
DeviceConfigurationOverride یک API فقط آزمایشی است که به شما امکان میدهد
پیکربندیهای مختلف دستگاه را بهصورت محلی برای محتوای @Composable
دردست آزمایش شبیهسازی کنید.
شی همراه DeviceConfigurationOverride دارای توابع افزونه زیر است که
ویژگیهای پیکربندی سطح دستگاه را ملغی میکند:
DeviceConfigurationOverride.DarkMode(): سیستم را برای استفاده از زمینه تیره یا زمینه روشن ملزم میکند.DeviceConfigurationOverride.FontScale(): مقیاس قلم سیستم را ملغی میکند.DeviceConfigurationOverride.FontWeightAdjustment(): تنظیمات وزن قلم سیستم را ملغی میکند.DeviceConfigurationOverride.ForcedSize(): صرفنظر از اندازه دستگاه، مقدار فضای مشخصی را اجبار میکند.DeviceConfigurationOverride.LayoutDirection(): جهت چیدمان (چپبهراست یا راستبهچپ) را ملغی میکند.DeviceConfigurationOverride.Locales(): مکان را ملغی میکند.DeviceConfigurationOverride.RoundScreen(): اگر صفحهنمایش گرد باشد، این مقدار جایگزین مقدار پیشفرض میشود.
برای اعمال یک ملغی خاص، محتوای تحت آزمایش را در یک فراخوانی به تابع سطح بالای
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") } }
مدیریت خطای سفارشی در آزمایشها
وقتی ادعایی ناموفق است، اشکالزدایی آزمایشهای واسط کاربری اغلب مستلزم بررسی وضعیت صفحه و سلسلهمراتب ترکیب است.
Compose خط لوله مدیریت خطای بومیای برای کارآمدتر کردن تشخیص خرابی ارائه میدهد. میتوانید درصورت خرابی، بهطور خودکار نماگرفتها و سلسلهمراتب واسط کاربر را ضبط کنید، یا کارگزارهای سفارشی را ثبت کنید تا تلهمتری خرابی را به ابزارهای خارجی ارسال کنید.
پیکربندی مدیریت خطا
برای پیکربندی مدیریت خطا، یک شیء TestFailurePolicy را به
ComposeUiTestConfig ارسال کنید.
ضبط کردن دادههای خطای داخلی
برای ضبط نماگرفتها و سلسلهمراتب میانای کاربری درصورت ناموفق بودن آزمایش، ویژگیهای
screenshotCaptureMode و uiHierarchyCaptureMode را در
TestFailurePolicy تنظیم کنید.
class MyComposeTest { private val customConfig = ComposeUiTestConfig( failurePolicy = TestFailurePolicy( screenshotCaptureMode = TestFailurePolicy.CaptureMode.Enabled, uiHierarchyCaptureMode = TestFailurePolicy.CaptureMode.Enabled ) ) @Test fun myFirstTest() = runComposeUiTest(config = customConfig) { // ... } }
استفاده از مدیریتکننده خطای سفارشی
برای تعریف رفتار سفارشی برای خطاهای آزمایش،
TestFailureHandler را به failureHandlers فهرست اضافه کنید. هر کنترلکننده
شیء FailureContext را دریافت میکند که حاوی خطای اصلی و
فهرستی از آرتیفکتهای تولیدشده توسط کنترلکنندههای خط لوله قبلی است.
class MyComposeTestWithHandler { private val customConfig = ComposeUiTestConfig( failurePolicy = TestFailurePolicy( screenshotCaptureMode = TestFailurePolicy.CaptureMode.Enabled, failureHandlers = listOf( TestFailureHandler { context -> val screenshot = context.artifacts.firstOrNull { it.type == FailureArtifact.Type.Screenshot } // ... } ) ) ) @get:Rule val rule = createComposeRule(config = customConfig) // ... }
پیکربندی ضبطها برای کل مجموعه آزمایش
با انتقال آرگومانهای اجراکننده ابزار دقیق در فایل build.gradle واحد خود، میتوانید ضبطهای آرتیفکت خرابی را برای کل مجموعه آزمایشی فعال کنید. این کار نیاز به بهروزرسانی فایلهای آزمایشی جداگانه را ازبین میبرد.
// build.gradle.kts
android {
defaultConfig {
// ...
testInstrumentationRunnerArguments["androidx.compose.ui.test.failure.isUiHierarchyCaptureEnabled"] = "true"
testInstrumentationRunnerArguments["androidx.compose.ui.test.failure.isScreenshotCaptureEnabled"] = "true"
}
}
اولویت پیکربندی
این چارچوب هم TestFailurePolicy محلی و هم آرگومانهای اجراکننده سطح مجموعه را ارزیابی میکند:
- اگر حالت
CaptureMode.Enabled/Disabledرا بهطور صریح در آزمایشfailurePolicyتنظیم کنید، این حالت بر آرگومان اجراکننده اولویت دارد. - اگر حالت را روی
CaptureMode.Unspecifiedتنظیم کنید (یاfailurePolicyرا رویnullبگذارید)، چارچوب به آرگومان اجراکننده برمیگردد.
منابع تکمیلی
- آزمایش برنامهها در Android: صفحه مقصد اصلی آزمایش Android نمای کلیتری از اصول و فنون آزمایش ارائه میدهد.
- اصول اولیه آزمایش: درباره مفاهیم اصلی پشت آزمایش برنامه Android بیشتر بدانید.
- آزمایشهای محلی: میتوانید برخیاز آزمایشها را بهصورت محلی، در ایستگاه کاری خودتان اجرا کنید.
- آزمایشهای ابزارگریشده: اجرای آزمایشهای ابزارگریشده نیز روال خوبی است. یعنی آزمایشهایی که مستقیماً در دستگاه اجرا میشوند.
- یکپارچهسازی مداوم: یکپارچهسازی مداوم به شما امکان میدهد آزمایشهایتان را در خط لوله استقرار ادغام کنید.
- آزمایش اندازههای مختلف صفحهنمایش: با دستگاههای بسیار زیادی که دراختیار کاربران قرار دارد، باید اندازههای مختلف صفحهنمایش را آزمایش کنید.
- Espresso: اگرچه برای واسطهای کاربر مبتنی بر «نما» درنظر گرفته شده است، دانش Espresso همچنان میتواند برای برخیاز جنبههای آزمایش Compose مفید باشد.