Espresso-Web היא נקודת כניסה לעבודה עם רכיבי ממשק משתמש של Android WebView. Espresso-Web משתמש מחדש ב-Atoms מ-WebDriver API הפופולרי כדי לבדוק ולשלוט בהתנהגות של WebView.
מתי כדאי להשתמש ב-Espresso-Web
אפשר להשתמש ב-Espresso-Web כדי לבדוק אפליקציות היברידיות, במיוחד את השילוב של רכיבי ממשק המשתמש המקוריים של האפליקציה עם רכיבי ממשק המשתמש שלה.WebView אפשר להשתמש ב-Espresso-Web API בשילוב עם ממשקי API אחרים של Espresso כדי ליצור אינטראקציה מלאה עם רכיבי אינטרנט בתוך אובייקטים של WebView.
אם אתם צריכים לבדוק רק את WebView עצמו, ולא את האינטראקציות בין WebView לרכיבים מקוריים באפליקציה, כדאי לכתוב בדיקת אינטרנט כללית באמצעות מסגרת כמו WebDriver. אם משתמשים במסגרת לבדיקת אתרים, לא צריך להשתמש במכשיר Android או במכונה וירטואלית של Java, ולכן הבדיקות יפעלו מהר יותר ובאופן מהימן יותר. עם זאת, Espresso-Web מאפשר לכם לעשות שימוש חוזר באטומי WebDriver מותאמים אישית, מה שמעניק לכם גמישות רבה, במיוחד כשאתם כותבים בדיקות שאתם מתכננים להריץ גם באפליקציות אינטרנט עצמאיות וגם באפליקציות שכוללות ממשק משתמש של Android.
איך זה עובד
בדומה לשיטה של Espresso onData()
, אינטראקציה WebView מורכבת מכמה אטומים.
אינטראקציות של WebView משתמשות בשילוב של שפת התכנות Java וגשר JavaScript כדי לבצע את העבודה. מכיוון שאין סיכוי להיווצרות תנאי מירוץ בחשיפת נתונים מסביבת JavaScript – כל מה ש-Espresso רואה בצד שמבוסס על Java הוא עותק מבודד – יש תמיכה מלאה בהחזרת נתונים מאובייקטים של Web.WebInteraction, כך שאפשר לאמת את כל הנתונים שמוחזרים מבקשה.
מה זה WebDriver Atom?
מסגרת WebDriver משתמשת ב-Atoms כדי למצוא ולשנות רכיבי אינטרנט באופן פרוגרמטי. WebDriver משתמש ב-Atoms כדי לאפשר שינוי של הדפדפן. מבחינה רעיונית, Atom דומה ל-ViewAction, יחידה עצמאית שמבצעת פעולה בממשק המשתמש. אתם חושפים את ה-Atoms באמצעות רשימה של שיטות מוגדרות, כמו findElement() ו-getElement(), כדי להפעיל את הדפדפן מנקודת המבט של המשתמש. עם זאת, אם משתמשים ישירות ב-framework של WebDriver, צריך לתזמן את ה-Atoms בצורה נכונה, וזה דורש לוגיקה מפורטת למדי.
ב-Espresso, המחלקות Web ו-Web.WebInteraction עוטפות את הקוד הסטנדרטי הזה ומעניקות תחושה של אינטראקציה עם אובייקטים של WebView בדומה ל-Espresso. לכן, בהקשר של WebView, נעשה שימוש ב-Atoms כתחליף ל-Espresso ViewMatchers ו-ViewActions.
ה-API נראה פשוט למדי:
Kotlin
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion)
Java
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion);
מידע נוסף זמין במאמרי העזרה של Selenium בנושא Atoms.
הטמעה של WebView
כדי להשתמש ב-WebView בבדיקות של האפליקציה, פועלים לפי ההנחיות שמפורטות בקטעים הבאים.
חבילות
כדי לכלול את Espresso-Web בפרויקט, מבצעים את השלבים הבאים:
- פותחים את קובץ
build.gradleשל האפליקציה. בדרך כלל זה לא הקובץbuild.gradleברמה העליונה, אלא הקובץapp/build.gradle. מוסיפים את השורה הבאה בתוך dependencies:
מגניב
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 ואילך של ספריית הבדיקות, לכן חשוב לעדכן גם את השורות האלה:
מגניב
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. לכן, כדי לתמוך בהערכת JavaScript, צריך להפעיל JavaScript ב-WebView שנבדק.
אפשר להפעיל את 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 ולוחצים על הלחצן Submit (שליחה), אותו טקסט מופיע ברכיב אחר באותו 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.