Mẫu kiểm thử phổ biến

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ị:

Để á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/Disabled trong failurePolicy kiể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 để failurePolicy là 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.