Espresso-Web هو نقطة دخول للعمل مع مكوّنات واجهة مستخدم Android WebView. تعيد Espresso-Web استخدام Atoms من واجهة برمجة التطبيقات الشائعة WebDriver API لفحص سلوك WebView والتحكّم فيه.
حالات استخدام Espresso-Web
استخدِم Espresso-Web لاختبار تطبيقاتك المختلطة، وخاصةً دمج مكوّنات واجهة المستخدم الأصلية لتطبيقك مع مكوّنات واجهة مستخدم WebView. يمكنك استخدام Espresso-Web API مع واجهات برمجة تطبيقات Espresso الأخرى للتفاعل بشكل كامل مع عناصر الويب داخل كائنات WebView.
إذا كنت بحاجة إلى اختبار WebView فقط، وليس
التفاعلات بين WebView والمكوّنات الأصلية في تطبيقك، ننصحك
بكتابة اختبار ويب عام باستخدام إطار عمل مثل WebDriver. إذا كنت تستخدم إطار عمل لاختبار الويب، لن تحتاج إلى استخدام جهاز Android أو جهاز Java الظاهري، ما يجعل اختباراتك تعمل بشكل أسرع وأكثر موثوقية. مع ذلك، تتيح لك Espresso-Web إعادة استخدام عناصر WebDriver المخصّصة، ما يمنحك الكثير من المرونة، خاصةً عند كتابة الاختبارات التي تخطط لتشغيلها على كل من تطبيقات الويب المستقلة والتطبيقات التي تتضمّن واجهة مستخدم Android.
آلية العمل
على غرار طريقة onData()
في Espresso، يتضمّن تفاعل WebView عدة عناصر Atoms.
تستخدم تفاعلات WebView مزيجًا من لغة برمجة Java وجسر JavaScript
لإجراء عملها. بما أنّه لا يمكن حدوث حالات تعارض بسبب عرض البيانات من بيئة JavaScript، لأنّ كل ما يراه Espresso على الجانب المستند إلى Java هو نسخة معزولة، يتم دعم عرض البيانات من كائنات Web.WebInteraction بشكل كامل، ما يتيح لك التحقّق من جميع البيانات التي يتم عرضها من طلب.
ما هو عنصر WebDriver Atom؟
يستخدم إطار عمل WebDriver عناصر Atoms للعثور على عناصر الويب ومعالجتها آليًا. يستخدم WebDriver عناصر Atoms للسماح بمعالجة المتصفّح. يشبه عنصر Atom من الناحية النظرية
ViewAction، وهو وحدة مستقلة
تنّفذ إجراءً في واجهة المستخدم. يمكنك عرض عناصر Atoms باستخدام قائمة بالطُرق المحدّدة، مثل findElement() وgetElement()، لتشغيل المتصفّح من وجهة نظر المستخدم. ومع ذلك، إذا كنت تستخدم إطار عمل WebDriver مباشرةً، يجب تنسيق عناصر Atoms بشكل صحيح، ما يتطلب منطقًا مطوّلاً إلى حد ما.
ضمن Espresso، يغلّف الصنفان Web
وWeb.WebInteraction
هذا الرمز الأساسي ويمنحان شعورًا مشابهًا لـ Espresso عند التفاعل مع كائنات WebView. لذا، في سياق WebView، تُستخدَم عناصر Atoms كـ
بديل لـ Espresso ViewMatchers و ViewActions التقليدية.
تبدو واجهة برمجة التطبيقات بسيطة جدًا بعد ذلك:
Kotlin
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion)
Java
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion);
لمزيد من المعلومات، يُرجى قراءة مستندات Selenium حول عناصر Atoms.
تنفيذ WebView
اتّبِع الإرشادات الموضّحة في الأقسام التالية للعمل مع
WebView في اختبارات تطبيقك.
إدارة الحِزم
لتضمين Espresso-Web في مشروعك، أكمل الخطوات التالية:
- افتح ملف
build.gradleالخاص بتطبيقك. عادةً ما يكون هذا الملف هوapp/build.gradleوليس ملفbuild.gradleعلى المستوى الأعلى. أضِف السطر التالي داخل التبعيات:
أنيق
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')
الاستخدام الشائع لواجهة برمجة التطبيقات
الطريقة 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 نفسه بعد إدخال نص في 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.