Đồng bộ hoá chương trình kiểm thử

Các quy trình kiểm thử Compose được đồng bộ hoá theo mặc định với giao diện người dùng. Khi bạn gọi một câu nhận định hoặc một hành động bằng ComposeTestRule, quy trình kiểm thử sẽ được đồng bộ hoá trước và chờ cho đến khi cây giao diện người dùng ở trạng thái rảnh.

Thông thường, bạn không phải thực hiện bất kỳ hành động nào. Tuy nhiên, có một số trường hợp phức tạp (edge case) mà bạn nên biết.

Khi một quy trình kiểm thử được đồng bộ hoá, ứng dụng Compose của bạn được đẩy nhanh thời gian bằng cách sử dụng đồng hồ ảo. Điều này có nghĩa là các quy trình kiểm thử Compose không chạy trong thời gian thực, cho nên các quy trình kiểm thử này có thể được thực hiện nhanh nhất trong khả năng.

Tuy nhiên, nếu bạn không sử dụng các phương thức đồng bộ hoá quy trình kiểm thử thì sẽ không xảy ra quá trình kết hợp lại và giao diện người dùng sẽ tạm dừng.

@Test
fun counterTest() {
    val myCounter = mutableStateOf(0) // State that can cause recompositions.
    var lastSeenValue = 0 // Used to track recompositions.
    composeTestRule.setContent {
        Text(myCounter.value.toString())
        lastSeenValue = myCounter.value
    }
    myCounter.value = 1 // The state changes, but there is no recomposition.

    // Fails because nothing triggered a recomposition.
    assertTrue(lastSeenValue == 1)

    // Passes because the assertion triggers recomposition.
    composeTestRule.onNodeWithText("1").assertExists()
}

Xin lưu ý rằng yêu cầu này chỉ áp dụng cho các hệ phân cấp Compose chứ không áp dụng cho phần còn lại của ứng dụng.

Tắt tính năng đồng bộ hoá tự động

Khi bạn gọi một câu nhận định (assertion) hoặc hành động thông qua ComposeTestRule chẳng hạn như assertExists(), quy trình kiểm thử của bạn sẽ được đồng bộ hoá với giao diện người dùng Compose. Trong một số trường hợp, bạn có thể dừng quá trình đồng bộ hoá này và tự điều khiển đồng hồ. Ví dụ: bạn có thể kiểm soát thời gian để chụp ảnh màn hình chính xác của một ảnh động tại thời điểm giao diện người dùng vẫn bận. Để tắt tính năng đồng bộ hoá tự động, hãy đặt thuộc tính autoAdvance trong mainClock thành false:

composeTestRule.mainClock.autoAdvance = false

Thông thường, sau đó bạn sẽ tự chuyển đến thời gian của mình. Bạn có thể chuyển đến chính xác một khung bằng advanceTimeByFrame() hoặc chuyển đến một khoảng thời gian cụ thể bằng advanceTimeBy():

composeTestRule.mainClock.advanceTimeByFrame()
composeTestRule.mainClock.advanceTimeBy(milliseconds)

Tài nguyên đang rảnh

Compose có thể đồng bộ hoá các quy trình kiểm thử và giao diện người dùng để mọi hành động và câu nhận định (assertion) được thực hiện ở trạng thái rảnh, chờ hoặc đẩy nhanh đồng hồ khi cần. Tuy nhiên, một số tác vụ không đồng bộ có kết quả ảnh hưởng đến trạng thái giao diện người dùng có thể chạy ở chế độ nền và quy trình kiểm thử không nhận biết được điều này.

Tạo và đăng ký các tài nguyên không hoạt động này trong chương trình kiểm thử để chúng được xem xét khi quyết định ứng dụng đang kiểm thử có bận hay ở trạng thái rảnh. Bạn không phải làm gì trừ phi cần đăng ký thêm các tài nguyên ở trạng thái rảnh, chẳng hạn như khi bạn chạy một công việc trong nền chưa được đồng bộ hoá với Espresso hoặc Compose.

API này rất giống với Tài nguyên không hoạt động của Espresso để cho biết đối tượng kiểm thử hiện đang rảnh hay bận. Sử dụng quy tắc kiểm thử Compose để đăng ký phương thức triển khai IdlingResource.

composeTestRule.registerIdlingResource(idlingResource)
composeTestRule.unregisterIdlingResource(idlingResource)

Đồng bộ hoá thủ công

Trong một số trường hợp, bạn phải đồng bộ hoá giao diện người dùng Compose với các phần khác trong quy trình kiểm thử hoặc ứng dụng đang kiểm thử.

Hàm waitForIdle() chờ Compose ở trạng thái rảnh, nhưng hàm này phụ thuộc vào thuộc tính autoAdvance:

composeTestRule.mainClock.autoAdvance = true // Default
composeTestRule.waitForIdle() // Advances the clock until Compose is idle.

composeTestRule.mainClock.autoAdvance = false
composeTestRule.waitForIdle() // Only waits for idling resources to become idle.

Lưu ý rằng trong cả hai trường hợp, waitForIdle() cũng sẽ chờ các lượt vẽ và bố cục đang chờ xử lý.

Ngoài ra, bạn có thể chuyển đồng hồ cho đến khi đáp ứng một điều kiện nhất định bằng advanceTimeUntil().

composeTestRule.mainClock.advanceTimeUntil(timeoutMs) { condition }

Lưu ý rằng điều kiện trên phải được kiểm tra trạng thái có thể bị ảnh hưởng bởi đồng hồ này (chỉ hoạt động với trạng thái Compose).

Chờ các điều kiện

Mọi điều kiện phụ thuộc vào công việc bên ngoài (chẳng hạn như tải dữ liệu hoặc hoạt động đo lường hoặc vẽ của Android (tức là đo lường hoặc vẽ bên ngoài Compose)) đều phải sử dụng một khái niệm chung hơn, chẳng hạn như waitUntil():

composeTestRule.waitUntil(timeoutMs) { condition }

Bạn cũng có thể sử dụng bất kỳ trình trợ giúp waitUntil nào:

composeTestRule.waitUntilAtLeastOneExists(matcher, timeoutMs)

composeTestRule.waitUntilDoesNotExist(matcher, timeoutMs)

composeTestRule.waitUntilExactlyOneExists(matcher, timeoutMs)

composeTestRule.waitUntilNodeCount(matcher, count, timeoutMs)

Tài nguyên khác

  • Kiểm thử ứng dụng trên Android: Trang đích chính của việc kiểm thử trên Android cung cấp cái nhìn rộng hơn về các nguyên tắc 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 chính liên quan đến 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ố 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. Điều này nghĩa là các bài 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 bài 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ới một số thiết bị được cung cấp cho người dùng, bạn nên kiểm thử cho nhiều kích thước màn hình.
  • Espresso: Mặc dù dành 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 kiểm thử Compose.