Đồ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 với ComposeTestRule, thì phép kiểm thử sẽ được đồng bộ hoá 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()
}

Lưu ý rằng yêu cầu này chỉ áp dụng cho 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 ở trạng thái 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 kiểm thử của bạn để chúng được sử dụng xem xét khi quyết định xem ứng dụng đang kiểm thử ở trạng thái bận hay ở trạng thái rảnh. Không thực hiện hành động trừ phi bạn cần đăng ký thêm tài nguyên không hoạt động, cho Ví dụ: nếu bạn chạy một công việc ở chế độ nền chưa được đồng bộ hoá bằng Espresso hoặc Soạn thư.

API này rất giống với Tài nguyên không tải của Espresso để cho biết liệu đối tượng kiểm thử không hoạt động hoặc bận. Sử dụng quy tắc kiểm thử Compose để đăng ký việ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 chờ bản vẽ và bố cục đang chờ xử lý thẻ và vé.

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ó điều kiện

Bất kỳ điều kiện nào 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 đo lường hoặc vẽ (tức là đo lường hoặc vẽ bên ngoài Compose), nên sử dụng 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:

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: Kiểm thử chính trên Android trang đích cung cấp cái nhìn rộng hơn về các nguyên tắc và kỹ thuật thử nghiệm.
  • Nguyên tắc cơ bản về việc kiểm thử: Tìm hiểu thêm về các khái niệm chính của việc kiểm thử ứng dụng Android.
  • Kiểm thử cục bộ: Bạn có thể chạy một số kiểm thử trên máy trạm của riêng bạn.
  • Kiểm thử đo lường: Kết quả này phù hợp để chạy cả các kiểm thử đo lường. Tức là các thử nghiệm chạy trực tiếp trên thiết bị.
  • Tích hợp liên tục: Khả năng tích hợp liên tục giúp bạn tích hợp các bài kiểm thử vào hoạt động triển khai quy trình.
  • Thử nghiệm nhiều kích thước màn hình: Bằng một số thiết bị có sẵn cho người dùng, bạn nên thử nghiệm các màn hình khác nhau kích thước.
  • Espresso: Mặc dù dành cho phương pháp dựa trên Khung hiển thị Giao diện người dùng, kiến thức về Espresso vẫn có thể hữu ích cho một số khía cạnh của Compose kiểm thử.