Dùng đối tượng kiểm thử trong Android

Khi thiết kế chiến lược kiểm thử cho một phần tử hoặc hệ thống, có ba yếu tố các khía cạnh kiểm thử liên quan:

  • Phạm vi: Kiểm thử tiếp cận bao nhiêu phần mã? Các bài kiểm thử có thể xác minh một phương thức, toàn bộ ứng dụng hoặc một định dạng nào đó trong khoảng giữa. Chiến lược phát hành đĩa đơn phạm vi được thử nghiệm là đang thử nghiệm và thường được gọi là Chủ đề trong Kiểm thử, mặc dù cũng là Hệ thống đang kiểm thử hoặc Đơn vị đang kiểm thử.
  • Tốc độ: Chương trình kiểm thử chạy nhanh đến mức nào? Tốc độ kiểm thử có thể thay đổi từ mili giây lên tới vài phút.
  • Độ trung thực: "Thế giới thực" là thử nghiệm? Ví dụ: nếu một phần của mã bạn đang kiểm thử có cần tạo một yêu cầu mạng không, mã kiểm thử có thực sự tạo ra yêu cầu mạng này hay nó làm giả kết quả? Nếu thử nghiệm thực sự kết nối với mạng, điều này có nghĩa là độ trung thực cao hơn. Sự đánh đổi ở đây là kiểm thử có thể mất nhiều thời gian chạy hơn, có thể dẫn đến lỗi nếu mạng bị rớt mạng, hoặc có thể tốn kém.

Vui lòng xem bài viết nội dung cần kiểm thử để tìm hiểu cách bắt đầu xác định chiến lược kiểm thử.

Tách biệt và phần phụ thuộc

Khi kiểm thử một phần tử hoặc hệ thống các phần tử, bạn sẽ thực hiện việc này để tách biệt. Cho ví dụ: để kiểm thử ViewModel, bạn không cần khởi động trình mô phỏng và chạy giao diện người dùng vì nó không (hoặc không nên) phụ thuộc vào khung Android.

Tuy nhiên, đối tượng kiểm thử có thể phụ thuộc vào các đối tượng khác để hoạt động. Cho thực thể khác, ViewModel có thể phụ thuộc vào kho lưu trữ dữ liệu để hoạt động.

Khi bạn cần cung cấp một phần phụ thuộc cho một đối tượng đang được kiểm thử, phương pháp phổ biến là tạo kiểm thử kép (hoặc đối tượng kiểm thử). Đối tượng kiểm thử kép là những đối tượng xem và hoạt động như các thành phần trong ứng dụng của bạn, nhưng chúng được tạo trong quá trình kiểm thử cung cấp hành vi hoặc dữ liệu cụ thể. Ưu điểm chính là các thẻ này giúp thử nghiệm nhanh hơn và đơn giản hơn.

Các loại đối tượng kiểm thử

Có nhiều loại kiểm thử kép:

Giả mạo Một kiểm thử kép có "hoạt động" việc triển khai lớp này, nhưng được triển khai theo cách phù hợp cho việc kiểm thử nhưng không phù hợp với quá trình sản xuất.

Ví dụ: một cơ sở dữ liệu trong bộ nhớ.

Hoạt động giả mạo không cần khung mô phỏng và có kích thước nhẹ. Chúng được ưu tiên.

Mô phỏng Kiểm thử kép hoạt động cách bạn lập trình để bot hoạt động và có kỳ vọng về các hoạt động tương tác của kiểm thử. Mô phỏng sẽ không vượt qua các lần kiểm thử nếu hoạt động tương tác của các mô hình đó không phù hợp với những yêu cầu mà bạn đặt ra. Nội dung mô phỏng thường được tạo dựa trên một khung mô phỏng để đạt được mục tiêu này.

Ví dụ: Xác minh rằng một phương thức trong cơ sở dữ liệu đã được gọi chính xác một lần.

Mục thay thế tạm thời Kiểm thử kép hoạt động như cách bạn lập trình để hoạt động đó hoạt động nhưng không kỳ vọng về hoạt động tương tác. Thường được tạo bằng khung mô phỏng. Vì thông tin giả mạo được ưu tiên hơn so với mã giả lập để đơn giản hoá.
Dummy Kiểm thử kép được truyền xung quanh nhưng không được sử dụng, chẳng hạn như nếu bạn chỉ cần cung cấp dưới dạng thông số.

Ví dụ: một hàm trống được truyền dưới dạng lệnh gọi lại lượt nhấp.

Gián điệp Trình bao bọc trên một đối tượng thực cũng theo dõi một số thông tin bổ sung, tương tự như bản mô phỏng. Người dùng thường nên tránh sử dụng các mô-đun này để tăng độ phức tạp. Vì vậy, nội dung giả mạo hoặc mô phỏng được ưu tiên hơn điệp viên.
Shadow Giả sử được sử dụng trong Robolectric.

Ví dụ về sử dụng giả mạo

Giả sử bạn muốn kiểm thử đơn vị một ViewModel phụ thuộc vào một giao diện có tên là UserRepository và hiển thị tên của người dùng đầu tiên cho giao diện người dùng. Bạn có thể tạo một kiểm thử giả mạo bằng cách triển khai giao diện và trả về các dữ liệu đã biết .

object FakeUserRepository : UserRepository {
    fun getUsers() = listOf(UserAlice, UserBob)
}

val const UserAlice = User("Alice")
val const UserBob = User("Bob")

UserRepository giả này không cần phụ thuộc vào dữ liệu cục bộ và dữ liệu từ xa mà phiên bản chính thức sẽ sử dụng. Tệp này nằm trong nguồn kiểm thử và sẽ không được giao cùng với ứng dụng sản xuất.

Phần phụ thuộc giả mạo có thể trả về dữ liệu đã biết mà không cần phụ thuộc vào nguồn dữ liệu từ xa
Hình 1: Phần phụ thuộc giả mạo trong một bài kiểm thử đơn vị.

Kiểm thử sau đây xác minh rằng ViewModel hiển thị chính xác người dùng đầu tiên vào chế độ xem.

@Test
fun viewModelA_loadsUsers_showsFirstUser() {
    // Given a VM using fake data
    val viewModel = ViewModelA(FakeUserRepository) // Kicks off data load on init

    // Verify that the exposed data is correct
    assertEquals(viewModel.firstUserName, UserAlice.name)
}

Việc thay thế UserRepository bằng mã giả rất dễ dàng trong kiểm thử đơn vị, vì ViewModel do người kiểm thử tạo. Tuy nhiên, việc thay thế có thể khó khăn các phần tử tuỳ ý trong kiểm thử lớn hơn.

Thay thế thành phần và tính năng chèn phần phụ thuộc

Khi chương trình kiểm thử không có quyền kiểm soát việc tạo hệ thống đang được kiểm thử, việc thay thế các thành phần cho đối tượng kiểm thử trở nên phức tạp hơn và đòi hỏi cấu trúc của ứng dụng để tuân theo thiết kế có thể kiểm thử.

Ngay cả những thử nghiệm lớn đầu cuối cũng có thể hưởng lợi từ việc sử dụng bộ đôi kiểm thử, chẳng hạn như kiểm thử giao diện người dùng được đo lường di chuyển qua toàn bộ luồng người dùng trong ứng dụng của bạn. Ngang bằng trong trường hợp đó, bạn có thể muốn làm cho thử nghiệm của mình ẩn. Tránh kiểm thử khép kín tất cả phần phụ thuộc bên ngoài, chẳng hạn như tìm nạp dữ liệu từ Internet. Chiến dịch này cải thiện độ tin cậy và hiệu suất.

Hình 2: Một chương trình kiểm thử lớn bao gồm hầu hết ứng dụng và giả mạo dữ liệu từ xa.

Bạn có thể thiết kế ứng dụng để đạt được tính linh hoạt này theo cách thủ công, nhưng bạn nên sử dụng khung chèn phần phụ thuộc như Hilt để thay thế các thành phần trong ứng dụng của bạn tại thời điểm thử nghiệm. Xem hướng dẫn kiểm thử Hilt.

Robolectric

Trên Android, bạn có thể sử dụng khung Robolectric, cung cấp một loại kiểm thử kép đặc biệt. Robolectric cho phép bạn chạy kiểm thử trên máy trạm hoặc trên môi trường tích hợp liên tục của bạn. Chiến dịch này sử dụng một JVM thông thường, không có trình mô phỏng hay thiết bị. Công cụ này mô phỏng hành vi tăng cường khung hiển thị, tải tài nguyên và các phần khác của khung Android bằng đối tượng kiểm thử có tên là bóng.

Robolectric là một trình mô phỏng, vì vậy, công cụ này sẽ không thay thế hoặc sử dụng các kiểm thử đơn vị đơn giản để kiểm thử khả năng tương thích. Tốc độ cao và giảm bớt chi phí độ trung thực thấp hơn trong một số trường hợp. Một phương pháp hay cho việc kiểm thử giao diện người dùng là làm cho chúng tương thích với cả Robolectric và kiểm thử đo lường cũng như quyết định thời điểm chạy tuỳ thuộc vào nhu cầu kiểm thử chức năng hoặc khả năng tương thích. Cả Espresso và các chương trình kiểm thử Compose có thể chạy trên Robolectric.