Compose cung cấp ComposeTestRule cho phép bạn viết các phép kiểm thử cho ảnh động theo cách thức xác định với toàn quyền kiểm soát trên đồng hồ kiểm thử. Tính năng này cho phép bạn xác minh các giá trị ảnh động trung gian. Ngoài ra, một thử nghiệm ảnh động có thể chạy nhanh hơn
thời lượng thực tế của ảnh động.
ComposeTestRule cho thấy đồng hồ thử nghiệm là mainClock. Bạn có thể thiết lập thuộc tính
autoAdvance thành false để kiểm soát đồng hồ trong mã thử nghiệm. Sau khi
bắt đầu ảnh động mà bạn muốn thử nghiệm, đồng hồ có thể được di chuyển về phía trước bằng
advanceTimeBy.
Cần lưu ý là advanceTimeBy không di chuyển đồng hồ một cách chính xác theo
thời lượng đã chỉ định. Thay vào đó, hệ thống sẽ làm tròn lên thời lượng gần nhất bằng
hệ số thời gian kết xuất khung hình.
@get:Rule val rule = createComposeRule() @Test fun testAnimationWithClock() { // Pause animations rule.mainClock.autoAdvance = false var enabled by mutableStateOf(false) rule.setContent { val color by animateColorAsState( targetValue = if (enabled) Color.Red else Color.Green, animationSpec = tween(durationMillis = 250) ) Box(Modifier.size(64.dp).background(color)) } // Initiate the animation. enabled = true // Let the animation proceed. rule.mainClock.advanceTimeBy(50L) // Compare the result with the image showing the expected result. // `assertAgainGolden` needs to be implemented in your code. rule.onRoot().captureToImage().assertAgainstGolden() }
Tối ưu hoá các thử nghiệm ảnh động
Khi kiểm thử ảnh động có độ trung thực cao, bạn thường cần tắt tính năng tự động chuyển tiếp và chuyển qua các khung hình theo cách thủ công để xác nhận các trạng thái giao diện người dùng trung gian. Đối với các vòng lặp cụ thể từng khung hình này, hãy sử dụng phương thức runWithoutImplicitWait để thực thi các câu khẳng định của bạn. Các truy vấn nút tiêu chuẩn (như onNodeWithTag hoặc fetchSemanticsNode) sẽ kích hoạt các hoạt động đồng bộ hoá ngầm không cần thiết khi bạn đang kiểm soát đồng hồ theo cách thủ công. Do đó, việc bỏ qua các truy vấn này sẽ tăng đáng kể thời gian chạy thử nghiệm.
Nguyên tắc sử dụng
- Quản lý đồng hồ theo cách thủ công: Sử dụng API này khi
mainClock.autoAdvanceđược đặt thànhfalsevà giao diện người dùng ở trạng thái ổn định, đã biết cho khung hình hiện tại. - Thực thi luồng giao diện người dùng: Để đảm bảo tính ổn định của cây giao diện người dùng, hãy gọi
runWithoutImplicitWaittrên luồng giao diện người dùng, chẳng hạn như vớirunOnUiThread. Việc chạy quy trình kiểm thử này ngoài Luồng giao diện người dùng sẽ khiến quy trình kiểm thử của bạn gặp phải tình huống tương tranh và đọc trạng thái lỗi thời. - Các câu khẳng định chỉ đọc: Khối này chỉ được chứa các câu khẳng định chỉ đọc. Mọi thao tác làm thay đổi trạng thái đều phải được thực hiện bên ngoài khối này.
Ví dụ
@Test fun runWithoutImplicitWaitSample() = runComposeUiTest { setContent { MainScreen() } mainClock.autoAdvance = false // Trigger an animation onNodeWithText("Start Animation").performClick() // Step through the animation frame-by-frame while (hasPendingWork()) { mainClock.advanceTimeByFrame() waitForIdle() runOnUiThread { // Suppress implicit synchronization inside this block to avoid redundant // waits on each node query, making the frame assertions execute much faster. runWithoutImplicitWait { val box1 = onNodeWithTag("Box1").fetchSemanticsNode() val box2 = onNodeWithTag("Box2").fetchSemanticsNode() val box3 = onNodeWithTag("Box3").fetchSemanticsNode() // Assert the exact intermediate state of all three properties for this frame assert(box1.boundsInRoot.right <= box2.boundsInRoot.left) assert(box2.boundsInRoot.right <= box3.boundsInRoot.left) } } } }
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt
- Kiểm thử bố cục Compose
- Những điểm khác cần cân nhắc
- Tuỳ chỉnh ảnh động