Espresso-Web là một điểm truy cập để làm việc với các thành phần giao diện người dùng Android WebView. Espresso-Web sử dụng lại các Atom từ WebDriver API phổ biến để kiểm tra và kiểm soát hành vi của WebView.
Trường hợp nên sử dụng Espresso-Web
Sử dụng Espresso-Web để kiểm thử các ứng dụng kết hợp, đặc biệt là việc tích hợp các thành phần giao diện người dùng gốc của ứng dụng với các thành phần giao diện người dùng WebView
. Bạn có thể sử dụng Espresso-Web API cùng với các Espresso API khác để tương tác hoàn toàn với các phần tử web bên trong các đối tượng WebView
.
Nếu bạn chỉ cần kiểm thử chính WebView
chứ không phải các hoạt động tương tác giữa WebView
và các thành phần gốc trong ứng dụng, hãy cân nhắc viết một kiểm thử web chung bằng cách sử dụng một khung như WebDriver. Nếu sử dụng một khung kiểm thử web, bạn không cần dùng thiết bị Android hoặc Máy ảo Java. Nhờ đó, các bài kiểm thử của bạn sẽ chạy nhanh hơn và đáng tin cậy hơn. Tuy nhiên, Espresso-Web cho phép bạn sử dụng lại các thành phần WebDriver tuỳ chỉnh, mang lại cho bạn nhiều sự linh hoạt, đặc biệt là khi viết các quy trình kiểm thử mà bạn dự định chạy trên cả ứng dụng web độc lập và ứng dụng có giao diện người dùng Android.
Cách hoạt động
Tương tự như phương thức onData()
của Espresso, một hoạt động tương tác WebView
bao gồm một số Atom.
Các hoạt động tương tác WebView
sử dụng kết hợp ngôn ngữ lập trình Java và cầu nối JavaScript để thực hiện công việc. Vì không có khả năng xảy ra tình trạng xung đột dữ liệu bằng cách hiển thị dữ liệu từ môi trường JavaScript (mọi thứ mà Espresso thấy ở phía dựa trên Java đều là một bản sao riêng biệt), nên việc trả về dữ liệu từ các đối tượng Web.WebInteraction
được hỗ trợ đầy đủ, cho phép bạn xác minh tất cả dữ liệu được trả về từ một yêu cầu.
WebDriver Atom là gì?
Khung WebDriver sử dụng Atom để tìm và thao tác với các phần tử web theo phương thức lập trình. WebDriver sử dụng các nguyên tử để cho phép thao tác với trình duyệt. Về mặt khái niệm, Atom tương tự như ViewAction
, một đơn vị độc lập thực hiện một hành động trong giao diện người dùng của bạn. Bạn hiển thị các Atom bằng cách sử dụng danh sách các phương thức đã xác định, chẳng hạn như findElement()
và getElement()
, để điều khiển trình duyệt theo quan điểm của người dùng. Tuy nhiên, nếu bạn sử dụng trực tiếp khung WebDriver, thì các Atom cần được điều phối đúng cách, đòi hỏi logic khá chi tiết.
Trong Espresso, các lớp Web
và Web.WebInteraction
sẽ bao bọc đoạn mã này và mang lại cảm giác tương tác với các đối tượng WebView giống như Espresso. Vì vậy, trong ngữ cảnh của WebView
, các Atom được dùng làm phương án thay thế cho ViewMatchers
và ViewActions
Espresso truyền thống.
Sau đó, API trông khá đơn giản:
Kotlin
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion)
Java
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion);
Để tìm hiểu thêm, hãy đọc tài liệu của Selenium về Atoms.
Triển khai WebView
Làm theo hướng dẫn trong các phần sau để làm việc với WebView
trong các kiểm thử của ứng dụng.
Gói
Để đưa Espresso-Web vào dự án của bạn, hãy hoàn tất các bước sau:
- Mở tệp
build.gradle
của ứng dụng. Đây thường không phải là tệpbuild.gradle
cấp cao nhất mà làapp/build.gradle
. Thêm dòng sau vào bên trong các phần phụ thuộc:
Groovy
androidTestImplementation 'androidx.test.espresso:espresso-web:3.6.1'
Kotlin
androidTestImplementation('androidx.test.espresso:espresso-web:3.6.1')
Espresso-Web chỉ tương thích với Espresso 2.2 trở lên và thư viện kiểm thử phiên bản 0.3 trở lên, vì vậy, hãy nhớ cập nhật cả những dòng đó:
Groovy
androidTestImplementation 'androidx.test:runner:1.6.1' androidTestImplementation 'androidx.test:rules:1.6.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
Kotlin
androidTestImplementation('androidx.test:runner:1.6.1') androidTestImplementation('androidx.test:rules:1.6.1') androidTestImplementation('androidx.test.espresso:espresso-core:3.6.1')
Các cách sử dụng API phổ biến
Phương thức onWebView()
là điểm truy cập chính khi làm việc với WebView trên Android bằng Espresso. Bạn dùng phương thức này để thực hiện các kiểm thử Espresso-Web, chẳng hạn như sau:
Kotlin
onWebView() .withElement(findElement(Locator.ID, "link_2")) // similar to onView(withId(...)) .perform(webClick()) // Similar to perform(click()) // Similar to check(matches(...)) .check(webMatches(getCurrentUrl(), containsString("navigation_2.html")))
Java
onWebView() .withElement(findElement(Locator.ID, "link_2")) // similar to onView(withId(...)) .perform(webClick()) // Similar to perform(click()) // Similar to check(matches(...)) .check(webMatches(getCurrentUrl(), containsString("navigation_2.html")));
Trong ví dụ này, Espresso-Web sẽ xác định vị trí của một phần tử DOM có mã nhận dạng là "link_2"
rồi nhấp vào phần tử đó. Sau đó, công cụ này sẽ xác minh rằng WebView gửi một yêu cầu GET chứa chuỗi "navigation_2.html"
.
Hỗ trợ JavaScript
Khi thực thi các kiểm thử, hệ thống sẽ thực hiện tất cả hoạt động tương tác WebView bằng JavaScript. Do đó, để hỗ trợ việc đánh giá JavaScript, WebView đang được kiểm thử phải bật JavaScript.
Bạn có thể buộc JavaScript phải được bật bằng cách gọi forceJavascriptEnabled()
dưới dạng một thao tác trong hoạt động đang được kiểm thử, như minh hoạ trong đoạn mã sau.
@RunWith(AndroidJUnit4::class) class MyTestSuite { @get:Rule val activityScenarioRule = activityScenarioRule<MyWebViewActivity>() @Test fun testWebViewInteraction() { onWebView().forceJavascriptEnabled() } }
Các lượt tương tác phổ biến trên web
Sau đây là một số hành động tương tác phổ biến với các đối tượng Web.WebInteraction
:
-
withElement()
tham chiếu đến một phần tử DOM trong WebView.Ví dụ:
Kotlin
onWebView().withElement(findElement(Locator.ID, "teacher"))
Java
onWebView().withElement(findElement(Locator.ID, "teacher"));
-
withContextualElement()
tham chiếu đến một phần tử DOM có phạm vi trong WebView, tương ứng với một phần tử DOM khác. Trước tiên, bạn nên gọiwithElement()
để thiết lập đối tượngWeb.WebInteraction
tham chiếu (phần tử DOM).Ví dụ:
Kotlin
.withElement(findElement(Locator.ID, "teacher")) .withContextualElement(findElement(Locator.ID, "person_name"))
Java
.withElement(findElement(Locator.ID, "teacher")) .withContextualElement(findElement(Locator.ID, "person_name"));
-
check()
đánh giá một điều kiện, đảm bảo rằng điều kiện đó giải quyết thànhtrue
.Ví dụ:
Kotlin
onWebView() .withElement(findElement(Locator.ID, "teacher")) .withContextualElement(findElement(Locator.ID, "person_name")) .check(webMatches(getText(), containsString("Socrates")))
Java
onWebView() .withElement(findElement(Locator.ID, "teacher")) .withContextualElement(findElement(Locator.ID, "person_name")) .check(webMatches(getText(), containsString("Socrates")));
-
perform()
thực thi một hành động trong WebView, chẳng hạn như nhấp vào một phần tử.Ví dụ:
Kotlin
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick())
Java
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick());
-
reset()
đưa WebView về trạng thái ban đầu. Điều này là cần thiết khi một thao tác trước đó (chẳng hạn như một lượt nhấp) gây ra thay đổi về điều hướng khiến các đối tượng ElementReference và WindowReference không truy cập được.Lưu ý: Mặc dù việc sử dụng
reset()
rất hữu ích khi đưa ra các khẳng định đối với quy trình làm việc nhiều trang, chẳng hạn như việc gửi biểu mẫu, nhưng các kiểm thử của bạn thường nên giới hạn phạm vi và tập trung vào một trang duy nhất.Ví dụ:
Kotlin
onWebView() .withElement(...) .perform(...) .reset()
Java
onWebView() .withElement(...) .perform(...) .reset();
Ví dụ
Ví dụ sau đây kiểm thử xem sau khi nhập văn bản vào WebView và chọn nút Gửi, văn bản đó có xuất hiện trong một phần tử khác trong cùng một WebView hay không:
Kotlin
const val MACCHIATO = "Macchiato" @RunWith(AndroidJUnit4::class) class MyEspressoWebTestSuite { @Test fun typeTextInInput_clickButton_SubmitsForm() { // Create an intent that displays a web form. val webFormIntent = Intent() // ... // Lazily launch the Activity with a custom start Intent per test. ActivityScenario.launchActivity(webFormIntent) // Selects the WebView in your layout. If you have multiple WebView // objects, you can also use a matcher to select a given WebView, // onWebView(withId(R.id.web_view)). onWebView() // Find the input element by ID. .withElement(findElement(Locator.ID, "text_input")) // Clear previous input and enter new text into the input element. .perform(clearElement()) .perform(DriverAtoms.webKeys(MACCHIATO)) // Find the "Submit" button and simulate a click using JavaScript. .withElement(findElement(Locator.ID, "submitBtn")) .perform(webClick()) // Find the response element by ID, and verify that it contains the // entered text. .withElement(findElement(Locator.ID, "response")) .check(webMatches(getText(), containsString(MACCHIATO))) } }
Java
public static final String MACCHIATO = "Macchiato"; @Test public void typeTextInInput_clickButton_SubmitsForm() { // Create an intent that displays a web form. Intent webFormIntent = new Intent(); // ... // Lazily launch the Activity with a custom start Intent per test. ActivityScenario.launchActivity(webFormIntent); // Selects the WebView in your layout. If you have multiple WebView objects, // you can also use a matcher to select a given WebView, // onWebView(withId(R.id.web_view)). onWebView() // Find the input element by ID. .withElement(findElement(Locator.ID, "text_input")) // Clear previous input and enter new text into the input element. .perform(clearElement()) .perform(DriverAtoms.webKeys(MACCHIATO)) // Find the "Submit" button and simulate a click using JavaScript. .withElement(findElement(Locator.ID, "submitBtn")) .perform(webClick()) // Find the response element by ID, and verify that it contains the // entered text. .withElement(findElement(Locator.ID, "response")) .check(webMatches(getText(), containsString(MACCHIATO))); }
Tài nguyên khác
Để biết thêm thông tin về cách sử dụng Espresso-Web trong các bài kiểm thử trên Android, hãy tham khảo các tài nguyên sau.
Mẫu
- WebBasicSample: Sử dụng Espresso-Web để tương tác với các đối tượng
WebView
.