Các hoạt động đóng vai trò là vùng chứa cho mọi lượt tương tác của người dùng trong ứng dụng của bạn, vì vậy, điều quan trọng là bạn phải kiểm thử cách các hoạt động của ứng dụng hoạt động trong các sự kiện ở cấp thiết bị, chẳng hạn như:
- Một ứng dụng khác (chẳng hạn như ứng dụng điện thoại trên thiết bị) làm gián đoạn hoạt động của ứng dụng.
- Hệ thống sẽ huỷ và tạo lại hoạt động của bạn.
- Người dùng đặt hoạt động của bạn trong một môi trường tạo cửa sổ mới, chẳng hạn như chế độ hình trong hình (PIP) hoặc chế độ nhiều cửa sổ.
Cụ thể, bạn cần đảm bảo rằng hoạt động của bạn hoạt động đúng cách để phản hồi các sự kiện được mô tả trong phần Vòng đời của activity.
Hướng dẫn này mô tả cách đánh giá khả năng duy trì tính toàn vẹn của dữ liệu và trải nghiệm người dùng tốt của ứng dụng khi các hoạt động của ứng dụng chuyển đổi qua nhiều trạng thái trong vòng đời của chúng.
Kiểm thử các hoạt động trong Compose
Khi kiểm thử một ứng dụng được tạo bằng Jetpack Compose, bạn thường dùng createAndroidComposeRule để chạy hoạt động và tương tác với các thành phần trên giao diện người dùng.
Tuy nhiên, việc kiểm thử các sự kiện ở cấp thiết bị (chẳng hạn như thay đổi về cấu hình hoặc hoạt động được đưa vào nền hoặc bị hệ thống huỷ) đòi hỏi bạn phải thao tác trực tiếp với vòng đời của hoạt động. Để làm việc này, bạn cần sử dụng khung ActivityScenario cơ bản.
Quy tắc kiểm thử Compose sẽ tự động bao bọc và quản lý trường hợp này cho bạn. Trong suốt hướng dẫn này, bạn sẽ thấy mẫu sau đây được dùng để thu hẹp khoảng cách giữa hoạt động kiểm thử giao diện người dùng hiện đại và hoạt động quản lý vòng đời tiêu chuẩn:
@get:Rule
val composeTestRule = createAndroidComposeRule<MyActivity>()
@Test fun testEvent() {
val scenario = composeTestRule.activityRule.scenario
// ...
}
Điều khiển trạng thái của một hoạt động
Một khía cạnh quan trọng của việc kiểm thử các hoạt động của ứng dụng là đặt các hoạt động của ứng dụng ở những trạng thái cụ thể. Để xác định phần "given" này trong các kiểm thử, hãy dùng các thực thể của ActivityScenario, thuộc thư viện AndroidX Test. Bằng cách sử dụng lớp này, bạn có thể đặt hoạt động của mình ở các trạng thái mô phỏng các sự kiện ở cấp thiết bị.
ActivityScenario là một API đa nền tảng mà bạn có thể dùng trong các kiểm thử đơn vị cục bộ và kiểm thử tích hợp trên thiết bị. Trên một thiết bị thực hoặc ảo, ActivityScenario cung cấp tính an toàn cho luồng, đồng bộ hoá các sự kiện giữa luồng đo lường của kiểm thử và luồng chạy hoạt động đang được kiểm thử.
API này đặc biệt phù hợp để đánh giá cách hoạt động đang được kiểm thử hoạt động khi bị huỷ hoặc được tạo. Phần này trình bày những trường hợp sử dụng phổ biến nhất liên quan đến API này.
Tạo một hoạt động
Để tạo hoạt động đang được kiểm thử, hãy thêm mã có trong đoạn mã sau:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEvent() {
launchActivity<MyActivity>().use {
}
}
}
Sau khi tạo hoạt động, ActivityScenario sẽ chuyển hoạt động sang trạng thái RESUMED. Trạng thái này cho biết hoạt động của bạn đang chạy và người dùng có thể nhìn thấy. Ở trạng thái này, bạn có thể tương tác với các thành phần kết hợp của hoạt động bằng cách sử dụng API kiểm thử Compose.
Google đề xuất bạn gọi close trên hoạt động khi kiểm thử hoàn tất.
Thao tác này sẽ dọn dẹp các tài nguyên liên kết và cải thiện độ ổn định của các kiểm thử. ActivityScenario triển khai Closeable, vì vậy, bạn có thể áp dụng tiện ích use để hoạt động tự động đóng.
Ngoài ra, bạn có thể sử dụng createAndroidComposeRule để tự động chạy Hoạt động trước mỗi bài kiểm thử, xử lý quy trình tháo dỡ và cấp cho bạn quyền truy cập vào cả phương thức kiểm thử giao diện người dùng Compose và ActivityScenario cơ bản. Ví dụ sau đây cho thấy cách xác định một quy tắc và lấy một thực thể của một kịch bản từ quy tắc đó:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@get:Rule
val composeTestRule = createAndroidComposeRule<MyActivity>()
@Test fun testEvent() {
val scenario = composeTestRule.activityRule.scenario
}
}
Chuyển hoạt động sang trạng thái mới
Để chuyển hoạt động sang một trạng thái khác, chẳng hạn như CREATED hoặc STARTED, hãy gọi moveToState. Thao tác này mô phỏng một tình huống trong đó hoạt động của bạn bị dừng hoặc tạm dừng, tương ứng, vì hoạt động đó bị gián đoạn bởi một ứng dụng khác hoặc một thao tác hệ thống.
Đoạn mã sau đây cho thấy ví dụ về cách sử dụng moveToState:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEvent() {
launchActivity<MyActivity>().use { scenario ->
scenario.moveToState(State.CREATED)
}
}
}
Xác định trạng thái của activity hiện tại
Để xác định trạng thái hiện tại của một hoạt động đang được kiểm thử, hãy lấy giá trị của trường state trong đối tượng ActivityScenario. Việc kiểm tra trạng thái của một hoạt động đang được kiểm thử sẽ đặc biệt hữu ích nếu hoạt động đó chuyển hướng đến một hoạt động khác hoặc tự kết thúc, như minh hoạ trong đoạn mã sau:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEvent() {
launchActivity<MyActivity>().use { scenario ->
scenario.onActivity { activity ->
startActivity(Intent(activity, MyOtherActivity::class.java))
}
val originalActivityState = scenario.state
}
}
}
Tạo lại hoạt động
Khi thiết bị sắp hết tài nguyên, hệ thống có thể hủy bỏ một Hoạt động, yêu cầu ứng dụng của bạn tạo lại Hoạt động đó khi người dùng quay lại ứng dụng. Để mô phỏng các tình trạng này, hãy gọi recreate:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEvent() {
launchActivity<MyActivity>().use { scenario ->
scenario.recreate()
}
}
}
Lớp ActivityScenario duy trì trạng thái của thực thể đã lưu của hoạt động và mọi đối tượng được chú thích bằng @NonConfigurationInstance. Các đối tượng này tải vào phiên bản mới của hoạt động đang được kiểm thử.
Truy xuất kết quả hoạt động
Để lấy mã kết quả hoặc dữ liệu được liên kết với một hoạt động đã hoàn tất, hãy lấy giá trị của trường result trong đối tượng ActivityScenario. Bằng cách sử dụng createAndroidComposeRule, bạn có thể dễ dàng kích hoạt thao tác trên giao diện người dùng để hoàn tất hoạt động, như trong đoạn mã sau:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@get:Rule
val composeTestRule = createAndroidComposeRule<MyActivity>()
@Test fun testResult() {
composeTestRule.onNodeWithTag("finish_button").performClick()
val scenario = composeTestRule.activityRule.scenario
val resultCode = scenario.result.resultCode
val resultData = scenario.result.resultData
}
}
Kích hoạt các thao tác trong hoạt động
Tất cả phương thức trong ActivityScenario đều là lệnh gọi chặn, vì vậy, API yêu cầu bạn chạy các phương thức này trong luồng đo lường.
Để kích hoạt các thao tác trong hoạt động đang được kiểm thử, hãy sử dụng các API kiểm thử Compose để tương tác với các thành phần kết hợp:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@get:Rule
val composeTestRule = createAndroidComposeRule<MyActivity>()
@Test fun testEvent() {
composeTestRule.onNodeWithText("Refresh").performClick()
}
}
Tuy nhiên, nếu cần gọi một phương thức cho chính hoạt động đó, bạn có thể thực hiện lệnh gọi một cách an toàn bằng cách sử dụng onActivity:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEvent() {
launchActivity<MyActivity>().use { scenario ->
scenario.onActivity { activity ->
activity.handleSwipeToRefresh()
}
}
}
}
Tài nguyên khác
Để biết thêm thông tin về kiểm thử, hãy xem các tài nguyên bổ sung sau: