Espresso-Web เป็นจุดแรกเข้าในการทำงานกับคอมโพเนนต์ UI ของ Android WebView Espresso-Web จะใช้ Atom ซ้ำจาก WebDriver API ยอดนิยมเพื่อตรวจสอบและควบคุมลักษณะการทำงานของ WebView
เมื่อใดที่ควรใช้ Espresso-Web
ใช้ Espresso-Web เพื่อทดสอบแอปแบบไฮบริด โดยเฉพาะการผสานรวมคอมโพเนนต์ UI ดั้งเดิมของแอปกับคอมโพเนนต์ UI ของ WebView
คุณใช้ Espresso-Web API ร่วมกับ Espresso API อื่นๆ เพื่อโต้ตอบกับองค์ประกอบเว็บภายในออบเจ็กต์ WebView ได้อย่างเต็มที่
หากต้องการทดสอบเฉพาะ WebView เอง ไม่ใช่การโต้ตอบระหว่าง WebView กับคอมโพเนนต์ดั้งเดิมในแอป ให้ลองเขียนการทดสอบเว็บทั่วไปโดยใช้เฟรมเวิร์ก เช่น WebDriver หากใช้เฟรมเวิร์กการทดสอบเว็บ คุณไม่จำเป็นต้องใช้อุปกรณ์ Android หรือ Java Virtual Machine ซึ่งจะช่วยให้การทดสอบทำงานได้รวดเร็วและเชื่อถือได้มากขึ้น อย่างไรก็ตาม Espresso-Web ช่วยให้คุณนำ WebDriver Atom ที่กำหนดเองกลับมาใช้ซ้ำได้ ซึ่งจะช่วยให้มีความยืดหยุ่นเป็นอย่างมาก โดยเฉพาะเมื่อเขียนการทดสอบที่คุณวางแผนที่จะเรียกใช้กับทั้งเว็บแอปแบบสแตนด์อโลนและแอปที่มี UI ของ Android
วิธีการทำงาน
การโต้ตอบ WebView ประกอบด้วย Atom หลายรายการ ซึ่งคล้ายคลึงกับเมธอด onData() ของ Espresso
การโต้ตอบ WebView ใช้ภาษาโปรแกรม Java ร่วมกับบริดจ์ JavaScript ในการทำงาน เนื่องจากไม่มีโอกาสที่จะเกิดภาวะแข่งขันโดยการเปิดเผยข้อมูลจากสภาพแวดล้อม JavaScript (ทุกสิ่งที่ Espresso เห็นในฝั่งที่ใช้ Java นั้นเป็นสำเนาที่แยกต่างหาก) ระบบจึงรองรับการส่งคืนข้อมูลจากออบเจ็กต์ Web.WebInteraction อย่างเต็มที่ ซึ่งช่วยให้คุณยืนยันข้อมูลทั้งหมดที่ส่งคืนจากคำขอได้
WebDriver Atom คืออะไร
เฟรมเวิร์ก WebDriver ใช้ Atom เพื่อค้นหาและจัดการองค์ประกอบของเว็บโดยใช้โปรแกรม WebDriver ใช้ Atom เพื่ออนุญาตการจัดการเบราว์เซอร์ ในเชิงแนวคิดแล้ว Atom จะคล้ายกับ ViewAction ซึ่งเป็นหน่วยแบบสแตนด์อโลนที่ดำเนินการใน UI คุณจะแสดง Atom โดยใช้รายการของเมธอดที่กำหนด เช่น findElement() และ getElement() เพื่อขับเคลื่อนเบราว์เซอร์จากมุมมองของผู้ใช้ อย่างไรก็ตาม หากคุณใช้เฟรมเวิร์ก WebDriver โดยตรง คุณจะต้องจัดการ Atom เป็นกลุ่มอย่างเหมาะสม ซึ่งต้องใช้ตรรกะที่ค่อนข้างซับซ้อน
ใน Espresso คลาส Web และ Web.WebInteraction จะทำหน้าที่ห่อหุ้ม Boilerplate นี้และมอบประสบการณ์การใช้งานที่เหมือนกับ Espresso ในการโต้ตอบกับออบเจ็กต์ WebView ดังนั้นในบริบทของ WebView ระบบจะใช้ Atom เป็นการแทนที่ Espresso ViewMatchers และ ViewActions แบบเดิม
จากนั้น API ก็จะดูเรียบง่ายขึ้น
Kotlin
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion)
Java
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion);
ดูข้อมูลเพิ่มเติมได้ที่เอกสารประกอบของ Selenium เกี่ยวกับ Atom
ติดตั้งใช้งาน WebView
ทำตามคำแนะนำที่แสดงในส่วนต่อไปนี้เพื่อทำงานกับ WebView ในการทดสอบของแอป
แพ็กเกจ
หากต้องการรวม Espresso-Web ไว้ในโปรเจ็กต์ ให้ทำตามขั้นตอนต่อไปนี้
- เปิดไฟล์
build.gradleของแอป โดยปกติแล้วไฟล์นี้จะไม่ใช่ไฟล์build.gradleระดับบนสุด แต่จะเป็นapp/build.gradle เพิ่มบรรทัดต่อไปนี้ภายในทรัพยากร Dependency
Groovy
androidTestImplementation 'androidx.test.espresso:espresso-web:3.6.1'
Kotlin
androidTestImplementation('androidx.test.espresso:espresso-web:3.6.1')
Espresso-Web ใช้ได้กับ Espresso 2.2 ขึ้นไปและไลบรารีการทดสอบเวอร์ชัน 0.3 ขึ้นไปเท่านั้น ดังนั้นโปรดตรวจสอบว่าคุณได้อัปเดตบรรทัดเหล่านั้นด้วย
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')
การใช้งาน API ทั่วไป
เมธอด onWebView() เป็นจุดแรกเข้าหลักเมื่อทำงานกับ WebView ใน Android โดยใช้ Espresso คุณใช้เมธอดนี้เพื่อทำการทดสอบ Espresso-Web เช่น การทดสอบต่อไปนี้ได้
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")));
ในตัวอย่างนี้ Espresso-Web จะค้นหาองค์ประกอบ DOM ที่มีรหัส "link_2" และคลิกองค์ประกอบนั้น จากนั้นเครื่องมือจะยืนยันว่า WebView ส่งคำขอ GET ที่มีสตริง "navigation_2.html"
การรองรับ JavaScript
เมื่อทำการทดสอบ ระบบจะโต้ตอบกับ WebView ทั้งหมดโดยใช้ JavaScript ดังนั้น WebView ที่อยู่ภายใต้การทดสอบต้องเปิดใช้ JavaScript เพื่อรองรับการประเมิน JavaScript
คุณบังคับให้เปิดใช้ JavaScript ได้โดยเรียก forceJavascriptEnabled() เป็นการดำเนินการในกิจกรรมภายใต้การทดสอบ ดังที่แสดงในข้อมูลโค้ดต่อไปนี้
@RunWith(AndroidJUnit4::class) class MyTestSuite { @get:Rule val activityScenarioRule = activityScenarioRule<MyWebViewActivity>() @Test fun testWebViewInteraction() { onWebView().forceJavascriptEnabled() } }
การโต้ตอบบนเว็บทั่วไป
การโต้ตอบทั่วไปกับออบเจ็กต์ Web.WebInteraction จะรวมถึงสิ่งต่อไปนี้
-
withElement()อ้างอิงองค์ประกอบ DOM ภายใน WebViewตัวอย่าง
Kotlin
onWebView().withElement(findElement(Locator.ID, "teacher"))
Java
onWebView().withElement(findElement(Locator.ID, "teacher"));
-
withContextualElement()อ้างอิงองค์ประกอบ DOM ที่กำหนดขอบเขตภายใน WebView โดยสัมพันธ์กับองค์ประกอบ DOM อื่น คุณควรเรียกใช้withElement()ก่อนเพื่อสร้างออบเจ็กต์อ้างอิงWeb.WebInteraction(องค์ประกอบ DOM)ตัวอย่าง
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()จะประเมินเงื่อนไขเพื่อให้แน่ใจว่าเงื่อนไขจะเป็นtrueตัวอย่าง
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()ดำเนินการภายใน WebView เช่น การคลิกองค์ประกอบตัวอย่าง
Kotlin
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick())
Java
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick());
-
reset()จะเปลี่ยน WebView กลับสู่สถานะเริ่มต้น ซึ่งจำเป็นเมื่อการดำเนินการก่อนหน้า เช่น การคลิก ทำให้เกิดการเปลี่ยนแปลงกับการนำทาง ซึ่งส่งผลให้ออบเจ็กต์ ElementReference และ WindowReference เข้าถึงไม่ได้หมายเหตุ: แม้ว่าการใช้
reset()จะมีประโยชน์เมื่อทำการยืนยันกับเวิร์กโฟลว์แบบหลายหน้า เช่น การส่งแบบฟอร์ม แต่โดยปกติแล้วการทดสอบควรจำกัดขอบเขตและมุ่งเน้นไปที่หน้าเดียวตัวอย่าง
Kotlin
onWebView() .withElement(...) .perform(...) .reset()
Java
onWebView() .withElement(...) .perform(...) .reset();
ตัวอย่าง
ตัวอย่างต่อไปนี้จะทดสอบว่าหลังจากป้อนข้อความลงใน WebView และเลือกปุ่มส่งแล้ว ข้อความเดียวกันจะปรากฏภายในองค์ประกอบอื่นใน WebView เดียวกันหรือไม่
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))); }
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ Espresso-Web ในการทดสอบ Android ได้ที่แหล่งข้อมูลต่อไปนี้
ตัวอย่าง
- WebBasicSample:
ใช้ Espresso-Web เพื่อโต้ตอบกับออบเจ็กต์
WebView