Khả năng tương tác

Compose tích hợp với các khung kiểm thử phổ biến.

Khả năng tương tác với Espresso

Trong một ứng dụng kết hợp, bạn có thể tìm thấy các thành phần Compose bên trong các hệ phân cấp view; cũng như có thể tìm thấy các khung hiển thị bên trong các composable Compose (thông qua composable AndroidView).

Không cần thực hiện bước đặc biệt nào để so khớp một trong hai loại này. Bạn so khớp các thành phần hiển thị bằng onView của Espresso và so khớp các phần tử Compose bằng ComposeTestRule.

@Test
fun androidViewInteropTest() {
    // Check the initial state of a TextView that depends on a Compose state.
    Espresso.onView(withText("Hello Views")).check(matches(isDisplayed()))
    // Click on the Compose button that changes the state.
    composeTestRule.onNodeWithText("Click here").performClick()
    // Check the new value.
    Espresso.onView(withText("Hello Compose")).check(matches(isDisplayed()))
}

Thêm ngữ nghĩa trong phạm vi hiển thị để kiểm thử khả năng tương tác của Compose

Phạm vi tìm kiếm Compose cho các Khung hiển thị cụ thể

Khi di chuyển giao diện người dùng phức tạp sang Compose, bạn có thể gặp phải các phần tử Compose giống hệt nhau được lồng trong nhiều Khung hiển thị Android truyền thống, chẳng hạn như trong RecyclerView hoặc ViewPager. Trong những trường hợp này, một thao tác tìm kiếm Compose tiêu chuẩn như onNodeWithText("Save") có thể gặp lỗi "Tìm thấy nhiều nút".

Thay vì sửa đổi mã sản xuất để chèn các thẻ kiểm thử động nhằm phân biệt các phần tử này, bạn có thể trực tiếp đặt phạm vi kiểm thử Compose cho một thành phần hiển thị Android cụ thể.

Sử dụng API onRootWithViewInteraction trên quy tắc kiểm thử. Hàm này chấp nhận một ViewInteraction Espresso, cho phép bạn tận dụng Espresso để cô lập một Khung hiển thị vùng chứa cụ thể và thực hiện các hoạt động tương tác Compose chỉ trong hệ phân cấp có phạm vi đó.

Tương tác với một mục trong danh sách

Nếu cần tương tác với một phần tử Compose bên trong một RecyclerViewhàng cụ thể, hãy dùng Espresso để xác định vị trí hàng, sau đó giới hạn phạm vi tương tác Compose của bạn trong hàng đó. Thao tác này sẽ bỏ qua các phần tử Compose giống hệt nhau trong tất cả các hàng khác.

@Test
fun testComposeButtonInsideRecyclerViewItem() = runComposeUiTest {
    // Scroll to the desired position using Espresso
    Espresso.onView(withId(recyclerViewId))
        .perform(RecyclerViewActions.scrollToPosition<MyViewHolder>(3))

    // Define an Espresso ViewInteraction that uniquely identifies the row
    val rowView = Espresso.onView(
        allOf(
            withId(rootViewId),
            hasDescendant(withText("Item #3"))
        )
    )

    // Scope the Compose search strictly to that specific row View
    onRootWithViewInteraction(rowView)
        .onNode(hasText("Like"))
        .performClick()
}

Giải quyết sự mơ hồ trong ViewPager

Khi có nhiều mảnh có bố cục Compose giống hệt nhau trong bộ nhớ cùng một lúc, bạn có thể giới hạn phạm vi tìm kiếm theo mã nhận dạng View gốc của mảnh cụ thể để tránh trường hợp trùng khớp không rõ ràng.

@Test
fun testComposeButtonInsideViewPagerItem() = runComposeUiTest {
    // Swipe to the desired page using Espresso
    Espresso.onView(withId(viewPagerViewId)).perform(swipeLeft())

    // Identify the specific container view using Espresso
    val fragmentB = Espresso.onView(withId(fragmentRootViewId))

    // The generic text "Save" is now unique within this view scope
    onRootWithViewInteraction(fragmentB)
        .onNode(hasText("Save"))
        .assertIsDisplayed()
}

Khả năng tương tác với UiAutomator

Theo mặc định, chỉ có thể truy cập thành phần kết hợp UiAutomator bằng các trình mô tả thuận tiện của chúng (văn bản hiển thị, thông tin mô tả nội dung, v.v.). Nếu muốn truy cập bất kỳ thành phần kết hợp nào bằng Modifier.testTag, bạn cần bật thuộc tính ngữ nghĩa testTagsAsResourceId cho cây con của thành phần kết hợp cụ thể. Việc kích hoạt hành vi này hữu ích đối với các thành phần kết hợp không có tên người dùng duy nhất nào khác, chẳng hạn như thành phần kết hợp có thể cuộn (ví dụ: LazyColumn).

Bạn chỉ có thể bật thuộc tính ngữ nghĩa một lần trong hệ phân cấp thành phần kết hợp để đảm bảo mọi thành phần kết hợp lồng với Modifier.testTag đều có thể truy cập được từ UiAutomator.

Scaffold(
    // Enables for all composables in the hierarchy.
    modifier = Modifier.semantics {
        testTagsAsResourceId = true
    }
){
    // Modifier.testTag is accessible from UiAutomator for composables nested here.
    LazyColumn(
        modifier = Modifier.testTag("myLazyColumn")
    ){
        // Content
    }
}

Bạn có thể truy cập mọi thành phần kết hợp với Modifier.testTag(tag) bằng cách sử dụng By.res(resourceName) dùng tag giống như resourceName.

val device = UiDevice.getInstance(getInstrumentation())

val lazyColumn: UiObject2 = device.findObject(By.res("myLazyColumn"))
// Some interaction with the lazyColumn.

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ích hợp liên tục cho phép bạn tích hợp các kiểm thử 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.