Kiểm thử hoạt động của ứng dụng

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 bài viết Vòng đời hoạt động.

Hướng dẫn này mô tả cách đánh giá khả năng duy trì tính toàn vẹn 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.

Đ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 trong quá trình kiểm thử khi hoạt động đó 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 phần tử View của hoạt động bằng cách sử dụng chương trình kiểm thử giao diện người dùng Espresso.

Google khuyến nghị bạn gọi close trên hoạt động khi quá trình kiểm thử hoàn tất. Điều này giúp 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 bài kiểm thử. ActivityScenario triển khai Closeable, vì vậy, bạn có thể áp dụng tiện ích use hoặc try-with-resources trong ngôn ngữ lập trình Java để hoạt động tự động đóng.

Ngoài ra, bạn có thể dùng ActivityScenarioRule để tự động gọi ActivityScenario.launch trước mỗi lượt kiểm thử và ActivityScenario.close khi huỷ kiểm thử. 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 kịch bản từ quy tắc đó:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @get:Rule var activityScenarioRule = activityScenarioRule<MyActivity>()

    @Test fun testEvent() {
        val scenario = activityScenarioRule.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 hoạt động 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ể huỷ 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 điều kiện 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, như trong đoạn mã sau:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testResult() {
        launchActivity<MyActivity>().use {
            onView(withId(R.id.finish_button)).perform(click())

            // Activity under test is now finished.

            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 trình so khớp khung hiển thị Espresso để tương tác với các phần tử trong khung hiển thị:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use {
            onView(withId(R.id.refresh)).perform(click())
        }
    }
}

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 một cách an toàn bằng cách triển khai ActivityAction:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEvent() {
        launchActivity<MyActivity>().use { scenario ->
            scenario.onActivity { activity ->
              activity.handleSwipeToRefresh()
            }
        }
    }
}