Kiểm thử điều hướng

1. Trước khi bắt đầu

Trong các lớp học lập trình trước đây, bạn đã tìm hiểu về cách di chuyển giữa các hoạt động. Trong lớp học lập trình này, bạn sẽ tìm hiểu một số phương thức để kiểm thử điều hướng (testing navigation) bằng cách sử dụng kiểm thử đo lường (instrumentation test).

Điều kiện tiên quyết

  • Bạn đã tạo thư mục kiểm thử trong Android Studio.
  • Bạn đã viết mã kiểm thử đơn vị và kiểm thử đo lường trong Android Studio.

Kiến thức bạn sẽ học được

  • Cách sử dụng kiểm thử đo lường để kiểm thử điều hướng vật lý giữa các hoạt động hoặc các mảnh.

Bạn cần có

  • Một máy tính đã cài đặt Android Studio.
  • Mã giải pháp cho ứng dụng Words (Từ vựng).

Tải mã khởi đầu xuống cho lớp học lập trình này

Trong lớp học lập trình này, bạn sẽ thêm kiểm thử đo lường vào mã giải pháp cho ứng dụng Words.

Để lấy đoạn mã cho lớp học lập trình này và mở đoạn mã đó trong Android Studio, hãy thực hiện các bước sau.

Lấy mã

  1. Nhấp vào URL được cung cấp. Thao tác này sẽ mở trang GitHub của dự án trong một trình duyệt.
  2. Trên trang GitHub của dự án, hãy nhấp vào nút Code (Mã), một hộp thoại sẽ xuất hiện.

5b0a76c50478a73f.png

  1. Trong hộp thoại này, hãy nhấp vào nút Download ZIP (Tải tệp ZIP xuống) để lưu dự án vào máy tính. Chờ quá trình tải xuống hoàn tất.
  2. Xác định vị trí của tệp trên máy tính (thường nằm trong thư mục Downloads (Tệp đã tải xuống)).
  3. Nhấp đúp vào tệp ZIP để giải nén. Thao tác này sẽ tạo một thư mục mới chứa các tệp dự án.

Mở dự án trong Android Studio

  1. Khởi động Android Studio.
  2. Trong cửa sổ Welcome to Android Studio (Chào mừng bạn đến với Android Studio), hãy nhấp vào Open an existing Android Studio project (Mở một dự án hiện có trong Android Studio).

36cc44fcf0f89a1d.png

Lưu ý: Nếu Android Studio đã mở sẵn thì thay vào đó, hãy chọn tuỳ chọn sau đây trong trình đơn File > New > Import Project (Tệp > Mới > Nhập dự án).

21f3eec988dcfbe9.png

  1. Trong hộp thoại Import Project (Nhập dự án), hãy chuyển đến nơi chứa thư mục dự án đã giải nén (thường nằm trong thư mục Downloads (Tệp đã tải xuống)).
  2. Nhấp đúp vào thư mục dự án đó.
  3. Chờ Android Studio mở dự án.
  4. Nhấp vào nút Run (Chạy) 11c34fc5e516fb1c.png để xây dựng và chạy ứng dụng. Hãy đảm bảo ứng dụng được dựng như mong đợi.
  5. Duyệt qua các tệp dự án trong cửa sổ công cụ Project (Dự án) để xem cách ứng dụng được thiết lập.

2. Tổng quan về ứng dụng khởi đầu

Ứng dụng Words (Từ vựng) bao gồm một màn hình chính cho thấy một danh sách, mỗi mục trong danh sách là một chữ cái của bảng chữ cái. Khi nhấp vào một chữ cái, người dùng sẽ được chuyển đến một màn hình cho thấy một danh sách các từ bắt đầu bằng chữ cái đó.

3. Các phương pháp hay nhất

Trong Kotlin, quy ước thông thường để đặt tên hàm là sử dụng "camel case" (quy tắc viết hoa kiểu lạc đà), trong đó chữ cái đầu tiên của tên hàm được viết thường và chữ cái đầu của các từ tiếp theo được viết hoa (ví dụ: myCamelCaseFunction()). Các phương thức kiểm thử mà chúng ta đã viết cho đến nay đều sử dụng tất cả chữ cái viết thường và dấu gạch dưới giữa các từ (ví dụ: my_test_function()). Đó là vì chúng ta muốn tên hàm được chi tiết để nêu rõ nội dung đang kiểm thử. Bằng cách đó, nếu kiểm thử không thành công thì chính tên đó sẽ cho biết rõ phương thức kiểm thử không thành công. Trong Kotlin, chúng ta thậm chí có thể dùng các dấu cách trong tên phương thức nếu đặt tên phương thức bằng dấu phẩy ngược, như trong ví dụ này: ``test function with spaces() (kiểm thử hàm có dấu cách). Hãy lưu ý rằng dấu phẩy ngược khác với dấu ngoặc kép. Bạn có thể tìm thấy dấu này trên khoá có dấu ngã (~). Điều này giúp tạo ra tên hàm mà con người có thể đọc được, giúp dễ dàng xác định lỗi nếu xảy ra lỗi.

Tuy nhiên, có một lưu ý đối với phương thức này là bạn phải triển khai một số hoạt động thiết lập. Hãy lưu ý rằng phần này là không bắt buộc. Bạn nên đọc nội dung này nhưng không cần thực hiện theo bất kỳ bước nào cho đến phần Tạo thư mục kiểm thử đo lường.

  1. Hãy lưu ý rằng dấu cách trong tên hàm chỉ hoạt động nếu bạn đang nhắm đến API 30 trong Android. Nếu không, bạn có thể gặp lỗi tương tự như sau:

4333fe8605801dba.png

Để thay đổi API, hãy chuyển đến app/build.gradle rồi sửa đổi minSdkVersion và/hoặc targetSdkVersion:

a6207c31c66ca185.png

Trong trường hợp này, targetSdkVersion được đặt thành 30 và đây là yêu cầu bắt buộc. Tuy nhiên, minSdkVersion19 nên chúng ta cần thay đổi giá trị này thành 30 để cho phép khoảng trắng trong tên hàm. Có thể điều này không phải lúc nào cũng thực tế, đó là lý do tính năng này "có thì tốt" nhưng không bắt buộc.

  1. Ngay cả khi đang nhắm đến API 30, bạn vẫn sẽ thấy rằng phương thức này được gạch chân màu đỏ cùng thông báo "Identifier not allowed in Android Projects" ("Giá trị nhận dạng không được cho phép trong Dự án Android").

d1330d69cc2472b1.png

Kiểm thử này vẫn sẽ thực thi và chạy đến khi hoàn thành, nhưng để loại bỏ dấu gạch dưới, hãy chuyển đến phần cài đặt/lựa chọn ưu tiên của Android Studio rồi chuyển đến Editor -> Inspections -> Kotlin Android -> Illegal Android Identifier -> Tests (Trình chỉnh sửa -> Kiểm tra -> Kotlin Android -> Trình nhận dạng Android bất hợp pháp -> Kiểm thử).

acc4a31499bdb25.png

Sau đó, bỏ đánh dấu ô Tests (Kiểm thử) rồi nhấp vào Apply (Áp dụng) hoặc OK.

aeb57d303996a3de.png

Bây giờ, phương thức không còn được gạch chân bằng màu đỏ nữa, miễn là bạn đưa tên phương thức vào dấu phẩy ngược.

a54f3eff47697024.png

4. Tạo thư mục kiểm thử

Tạo thư mục kiểm thử đo lường cho ứng dụng Words.

5. Tạo lớp kiểm thử đo lường

Tạo một lớp mới tên là NavigationTests.kt.

9d9ee307b4773b7.png

6. Viết kiểm thử điều hướng

  1. Chỉ định một trình chạy kiểm thử.
@RunWith(AndroidJUnit4::class)
  1. Sau đó, hãy khởi động hoạt động chính.
@get:Rule
val activity = ActivityScenarioRule(MainActivity::class.java)
  1. Bây giờ, hãy tạo một phương thức tên là navigate_to_word().
@Test
fun navigate_to_word() {
}
  1. Trong các phương thức navigate_to_word(), chúng ta phải chọn một mục trong danh sách cần chọn. Mục do chúng tôi chọn là tuỳ ý và bạn có thể thực hiện bằng nhiều cách. Chúng ta có thể chọn một mục dựa trên vị trí của mục đó trong trình chuyển đổi hoặc chúng ta có thể chọn một mục dựa trên văn bản (tức là chữ cái) trong mục đó. Hãy nhớ rằng nếu chọn tương tác trực tiếp với RecyclerView thì bạn sẽ phải có phần phụ thuộc sau:
dependencies {
    ...
    androidTestImplementation
‘com.android.support.test.espresso:espresso-contrib:3.0.2'
}

Mặt khác, nếu chọn một mục bằng văn bản thì bạn có thể sử dụng phương thức withText() mà bạn đã sử dụng trong các lớp học lập trình trước. Quan trọng là bạn phải lưu ý rằng nếu sử dụng phương thức này và văn bản không xuất hiện trên màn hình, thì kiểm thử sẽ không thành công. Chúng ta sẽ xem xét vấn đề này sau.

  1. Hãy xem bạn có thể thử áp dụng cả hai phương thức hay không. Đừng quên rằng mục tiêu của chúng ta là nhấp vào thành phần giao diện người dùng sau khi tìm thấy thành phần đó.

Cả hai phương thức này đều xuất hiện ở đây cùng ý định nhấp vào một mục có chữ "C" làm ví dụ.

onView(withText("C")).perform(click())
onView(withId(R.id.recycler_view))
   .perform(RecyclerViewActions
       .actionOnItemAtPosition<RecyclerView.ViewHolder>(2, click()))

Hãy dành chút thời gian để xem xét kỹ cả hai phương pháp này. Nếu bạn chạy cả hai phương thức và theo dõi trình mô phỏng hoặc thiết bị, thì bạn sẽ thấy cả hai trình này đều hoạt động. Việc sử dụng RecyclerViewActions đòi hỏi thêm mã, nhưng có lợi thế rõ ràng là có thể nhấp vào mục bất kỳ mà không cần thực hiện thêm thao tác nào. Hãy thử phương thức đầu tiên, nhưng thay đổi chữ "C" thành "Z" rồi chạy lại kiểm thử. Bạn sẽ thấy thông báo kiểm thử không thành công cùng lỗi sau: androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with text: is "Z" (Không tìm thấy thành phần hiển thị trong hệ phân cấp phù hợp: với văn bản: "Z").

3c518d4b00624af3.png

Điều này là do "Z" nằm ở cuối danh sách và ngoài màn hình khi chúng ta khởi chạy ứng dụng và người dùng phải cuộn xuống. Thường thì phương thức RecyclerViewAction sẽ xử lý vấn đề này. Hãy thử truyền 25 làm giá trị vị trí và theo dõi trình mô phỏng hoặc thiết bị.

  1. Nếu đã chạy các ví dụ nêu trên, bạn sẽ thấy rằng chúng ta đã khởi chạy thành công hoạt động tiếp theo, nhưng chúng ta muốn xác nhận điều đó bằng một câu nhận định. Nếu bạn chạy ứng dụng đó và nhấp vào mục bất kỳ trong danh sách, thì bạn sẽ thấy rằng tiêu đề trong thanh ứng dụng có nội dung "Words That Start With __" ("Từ bắt đầu bằng __", trong đó, khoảng trống là chữ cái bạn đã nhấp vào. Chúng tôi có thể sử dụng dữ liệu này để kiểm tra xem phần điều hướng có hoạt động đúng cách hay không. Chúng ta chỉ cần xác nhận rằng chuỗi chính xác (theo sau là chữ cái chúng ta nhấp vào) đã xuất hiện. Bạn đã đưa ra câu nhận định tương tự trong các lớp học trình trước đó, vậy nên hãy xem liệu bạn có thể tự thực hiện việc này hay không!
onView(withText("Words That Start With C")).check(matches(isDisplayed()))

7. Bài học khái niệm và các phương pháp hay nhất

Có hai thuật ngữ rất quan trọng dùng trong kiểm thử: "false positive" (dương tính giả) và "false negative" (âm tính giả).

"False positive" là khi kiểm thử có kết quả thành công, mặc dù đã xảy ra lỗi và kết quả kiểm thử không thành công. Tương tự, "false negative" là khi kiểm thử có kết quả không thành công dù phương thức được áp dụng chính xác và kết thử đáng lẽ phải thành công.

Trong kiểm thử đã viết ở trên, chúng ta đã mã hoá cứng chuỗi mà chúng ta đang tìm kiếm. Trên khía cạnh mã, sẽ dễ dàng hơn nếu tạo chuỗi qua các tài nguyên chuỗi, như đã thực hiện trong ứng dụng. Chuỗi này hoạt động hơi khác so với chuỗi trong mã ứng dụng bình thường, nhưng vẫn có thể áp dụng. Tuy nhiên, có thể hoạt động tạo chuỗi theo phương thức này sẽ không thành công vì hoạt động tạo chuỗi này về mặt kỹ thuật là logic nghiệp vụ. Nếu hoạt động tạo chuỗi trong kiểm thử không thành công giống như hoạt động tạo chuỗi trong mã ứng dụng, thì có thể sẽ có kết quả false positive. Điều này là do cả hai đoạn mã tạo cùng một chuỗi không chính xác nên văn bản không chính xác trên kiểm thử khớp với văn bản không chính xác xuất hiện trong ứng dụng. Do đó, tốt hơn là bạn nên mã hoá chuỗi thành giá trị mà chúng ta mong đợi.

8. Mã giải pháp

9. Xin chúc mừng

Trong lớp học lập trình này, chúng ta:

  • Tìm hiểu cách tạo tên hàm chi tiết cho kiểm thử.
  • Tìm hiểu cách kiểm thử điều hướng vật lý bằng hoạt động hoặc mảnh.
  • Tìm hiểu về "false positive" và "false negative".