Bạn có thể kiểm thử ứng dụng Compose bằng các phương pháp và mẫu đã được thiết lập sẵn.
Kiểm thử riêng biệt
ComposeTestRule cho phép bạn bắt đầu một hoạt động cho thấy thành phần kết hợp bất kỳ: toàn bộ ứng dụng, một màn hình đơn lẻ hoặc một phần tử nhỏ. Đây là một phương pháp hay để kiểm tra xem các thành phần kết hợp có được đóng gói chính xác và hoạt động độc lập hay không, cho phép việc kiểm thử giao diện người dùng trở nên dễ dàng hơn và tập trung hơn.
Điều này không có nghĩa là bạn chỉ nên tạo các quy trình kiểm thử đơn vị khi kiểm thử giao diện người dùng. Việc kiểm thử trong phạm vi các phần lớn hơn trên giao diện người dùng cũng rất quan trọng.
Truy cập vào hoạt động và tài nguyên sau khi thiết lập nội dung của riêng bạn
Thông thường, bạn cần thiết lập nội dung đang kiểm thử bằng composeTestRule.setContent, đồng thời cần truy cập vào các tài nguyên hoạt động, chẳng hạn như để xác nhận rằng văn bản hiển thị khớp với tài nguyên chuỗi. Tuy nhiên, bạn không thể gọi setContent trên một quy tắc được tạo bằng createAndroidComposeRule() nếu hoạt động này đã gọi quy tắc đó.
Mẫu phổ biến dùng để thực hiện việc này là tạo AndroidComposeTestRule bằng một hoạt động trống, chẳng hạn như 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()
}
}
Xin lưu ý rằng bạn cần thêm ComponentActivity vào tệp AndroidManifest.xml của ứng dụng. Hãy bật tính năng đó bằng cách thêm phần phụ thuộc này vào mô-đun:
debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")
Thuộc tính ngữ nghĩa tùy chỉnh
Bạn có thể tạo các thuộc tính ngữ nghĩa tuỳ chỉnh để hiển thị thông tin cho quy trình kiểm thử.
Để thực hiện việc này, hãy khai báo một SemanticsPropertyKey mới và cung cấp thuộc tính đó bằng cách sử dụng SemanticsPropertyReceiver.
// Creates a semantics property of type Long.
val PickedDateKey = SemanticsPropertyKey<Long>("PickedDate")
var SemanticsPropertyReceiver.pickedDate by PickedDateKey
Bây giờ, hãy sử dụng thuộc tính đó trong đối tượng sửa đổi semantics:
val datePickerValue by remember { mutableStateOf(0L) }
MyCustomDatePicker(
modifier = Modifier.semantics { pickedDate = datePickerValue }
)
Trong các quy trình kiểm thử, hãy sử dụng SemanticsMatcher.expectValue để xác nhận giá trị của thuộc tính:
composeTestRule
.onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
.assertExists()
Xác minh quá trình khôi phục trạng thái
Xác minh rằng trạng thái của các phần tử Compose được khôi phục chính xác khi hoạt động hoặc quy trình được tạo lại. Thực hiện các hoạt động kiểm tra như vậy mà không cần tạo lại hoạt động bằng lớp StateRestorationTester.
Với lớp này, bạn có thể mô phỏng quá trình tạo lại một thành phần kết hợp. Việc xác minh quá trình triển khai rememberSaveable sẽ đặc biệt hữu ích.
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.
}
}
Kiểm thử nhiều cấu hình thiết bị
Ứng dụng Android cần phải thích ứng với nhiều điều kiện thay đổi: kích thước cửa sổ, ngôn ngữ, cỡ chữ, giao diện tối và sáng, v.v. Hầu hết các điều kiện này đều bắt nguồn từ các giá trị ở cấp thiết bị do người dùng kiểm soát và được hiển thị bằng thực thể Configuration hiện tại. Việc kiểm thử các cấu hình khác nhau trực tiếp trong một kiểm thử là rất khó vì kiểm thử phải định cấu hình các thuộc tính ở cấp thiết bị.
DeviceConfigurationOverride là một API chỉ dùng để kiểm thử, cho phép bạn mô phỏng nhiều cấu hình thiết bị theo cách được bản địa hoá cho nội dung @Composable đang được kiểm thử.
Đối tượng đồng hành của DeviceConfigurationOverride có các hàm tiện ích sau đây, ghi đè các thuộc tính cấu hình ở cấp thiết bị:
DeviceConfigurationOverride.DarkMode(): Ghi đè hệ thống thành giao diện tối hoặc giao diện sáng.DeviceConfigurationOverride.FontScale(): Ghi đè tỷ lệ phông chữ hệ thống.DeviceConfigurationOverride.FontWeightAdjustment(): Ghi đè chế độ điều chỉnh độ đậm phông chữ của hệ thống.DeviceConfigurationOverride.ForcedSize(): Buộc một lượng không gian cụ thể bất kể kích thước thiết bị.DeviceConfigurationOverride.LayoutDirection(): Ghi đè hướng bố cục (từ trái sang phải hoặc từ phải sang trái).DeviceConfigurationOverride.Locales(): Ghi đè locale.DeviceConfigurationOverride.RoundScreen(): Ghi đè nếu màn hình có dạng tròn.
Để áp dụng một chế độ ghi đè cụ thể, hãy gói nội dung đang được kiểm thử trong một lệnh gọi đến hàm cấp cao nhất DeviceConfigurationOverride(), truyền chế độ ghi đè để áp dụng dưới dạng tham số.
Ví dụ: mã sau đây áp dụng cơ chế ghi đè DeviceConfigurationOverride.ForcedSize() để thay đổi mật độ cục bộ, buộc composable MyScreen phải hiển thị trong một cửa sổ ngang lớn, ngay cả khi thiết bị đang chạy kiểm thử không trực tiếp hỗ trợ kích thước cửa sổ đó:
composeTestRule.setContent { DeviceConfigurationOverride( DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp)) ) { MyScreen() // Will be rendered in the space for 1280dp by 800dp without clipping. } }
Để áp dụng nhiều chế độ ghi đè cùng nhau, hãy sử dụng DeviceConfigurationOverride.then():
composeTestRule.setContent { DeviceConfigurationOverride( DeviceConfigurationOverride.FontScale(1.5f) then DeviceConfigurationOverride.FontWeightAdjustment(200) ) { Text(text = "text with increased scale and weight") } }
Xử lý lỗi tuỳ chỉnh trong kiểm thử
Việc gỡ lỗi kiểm thử giao diện người dùng thường yêu cầu kiểm tra trạng thái màn hình và hệ phân cấp thành phần khi một câu nhận định không thành công.
Compose cung cấp một quy trình xử lý lỗi gốc để đơn giản hoá việc chẩn đoán. Bạn có thể tự động chụp ảnh màn hình và hệ phân cấp giao diện người dùng khi xảy ra lỗi hoặc đăng ký trình xử lý tuỳ chỉnh để chuyển tiếp dữ liệu đo từ xa về sự cố đến các công cụ bên ngoài.
Định cấu hình xử lý lỗi
Để định cấu hình cách xử lý lỗi, hãy truyền đối tượng TestFailurePolicy đến ComposeUiTestConfig.
Ghi lại cấu phần phần mềm lỗi tích hợp sẵn
Để chụp ảnh màn hình và phân cấp giao diện người dùng khi kiểm thử không thành công, hãy đặt các thuộc tính screenshotCaptureMode và uiHierarchyCaptureMode trong TestFailurePolicy.
class MyComposeTest { private val customConfig = ComposeUiTestConfig( failurePolicy = TestFailurePolicy( screenshotCaptureMode = TestFailurePolicy.CaptureMode.Enabled, uiHierarchyCaptureMode = TestFailurePolicy.CaptureMode.Enabled ) ) @Test fun myFirstTest() = runComposeUiTest(config = customConfig) { // ... } }
Sử dụng trình xử lý lỗi tuỳ chỉnh
Để xác định hành vi tuỳ chỉnh cho các lỗi kiểm thử, hãy thêm TestFailureHandler vào danh sách failureHandlers. Mỗi trình xử lý nhận được một đối tượng FailureContext chứa lỗi ban đầu và danh sách cấu phần phần mềm do các trình xử lý quy trình trước đó tạo ra.
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) // ... }
Định cấu hình ảnh chụp cho toàn bộ bộ kiểm thử
Bạn có thể bật tính năng chụp cấu phần phần mềm lỗi cho toàn bộ bộ kiểm thử bằng cách truyền các đối số trình chạy đo lường trong tệp build.gradle của mô-đun. Điều này giúp bạn không cần phải cập nhật từng tệp kiểm thử.
// build.gradle.kts
android {
defaultConfig {
// ...
testInstrumentationRunnerArguments["androidx.compose.ui.test.failure.isUiHierarchyCaptureEnabled"] = "true"
testInstrumentationRunnerArguments["androidx.compose.ui.test.failure.isScreenshotCaptureEnabled"] = "true"
}
}
Mức độ ưu tiên của cấu hình
Khung này đánh giá cả đối số trình chạy TestFailurePolicy cục bộ và cấp bộ:
- Nếu bạn đặt rõ một chế độ thành
CaptureMode.Enabled/DisabledtrongfailurePolicykiểm thử, thì chế độ này sẽ ghi đè đối số trình chạy. - Nếu bạn đặt chế độ thành
CaptureMode.Unspecified(hoặc đểfailurePolicylànull), thì khung sẽ quay lại đối số trình chạy.
Tài nguyên khác
- Kiểm thử ứng dụng trên Android: Trang đích chính về kiểm thử trên Android cung cấp thông tin tổng quan về các nguyên tắc cơ bản và kỹ thuật kiểm thử.
- Nguyên tắc cơ bản về kiểm thử: Tìm hiểu thêm về các khái niệm cốt lõi đằng sau việc kiểm thử một ứng dụng Android.
- Kiểm thử cục bộ: Bạn có thể chạy một số bài kiểm thử cục bộ trên máy trạm của riêng mình.
- Kiểm thử đo lường: Bạn cũng nên chạy kiểm thử đo lường. Tức là các kiểm thử chạy trực tiếp trên thiết bị.
- Tích hợp liên tục: Tính năng tích hợp liên tục cho phép bạn tích hợp các thử nghiệm vào quy trình triển khai.
- Kiểm thử nhiều kích thước màn hình: Vì người dùng có thể sử dụng nhiều thiết bị, nên bạn cần kiểm thử đối với nhiều kích thước màn hình.
- Espresso: Mặc dù được thiết kế cho giao diện người dùng dựa trên Khung hiển thị, nhưng kiến thức về Espresso vẫn có thể hữu ích cho một số khía cạnh của hoạt động kiểm thử trong Compose.