Espresso Web

Espresso-Web نقطه ورودی برای کار با مؤلفه‌های میانای کاربر «وب‌نمای Android» است. Espresso-Web از Atoms از WebDriver API محبوب برای بررسی و کنترل رفتار WebView استفاده می‌کند.

زمان استفاده از Espresso-Web

از Espresso-Web برای آزمایش برنامه‌های ترکیبی خود استفاده کنید، به‌ویژه ادغام مؤلفه‌های UI بومی برنامه شما با مؤلفه‌های UI WebView آن. می‌توانید از Espresso-Web API در ترکیب با دیگر Espresso APIها برای تعامل کامل با عناصر وب در اشیای WebView استفاده کنید.

اگر لازم است فقط خود WebView را آزمایش کنید و نه تعاملات بین WebView و مؤلفه‌های بومی در برنامه‌تان، نوشتن آزمایش وب عمومی بااستفاده از چارچوبی مانند WebDriver را درنظر بگیرید. اگر از چارچوب آزمایش وب استفاده می‌کنید، نیازی به استفاده از دستگاه Android یا «ماشین مجازی جاوا» ندارید، که باعث می‌شود آزمایش‌هایتان سریع‌تر و مطمئن‌تر اجرا شود. بااین‌حال، Espresso-Web به شما امکان می‌دهد از اتم‌های WebDriver سفارشی خودتان مجدداً استفاده کنید که انعطاف‌پذیری زیادی به شما می‌دهد، به‌ویژه هنگام نوشتن آزمایش‌هایی که قصد دارید دربرابر برنامه‌های وب مستقل و برنامه‌هایی که شامل واسط کاربر Android هستند اجرا کنید.

روش کار

مشابه روش onData() Espresso، تعامل WebView شامل چندین Atom است. تعاملات WebView برای انجام کارشان از ترکیبی از زبان برنامه‌نویسی جاوا و پل جاوا اسکریپت استفاده می‌کنند. Because there is no chance of introducing race conditions by exposing data from the JavaScript environment—everything Espresso sees on the Java-based side is an isolated copy—returning data from Web.WebInteraction objects is fully supported, allowing you to verify all data that’s returned from a request.

WebDriver Atom چیست؟

چارچوب WebDriver از Atoms برای یافتن و دستکاری عناصر وب به‌صورت برنامه‌نویسی‌شده استفاده می‌کند. WebDriver از Atoms برای دستکاری مرورگر استفاده می‌کند. یک Atom ازنظر مفهومی شبیه به ViewAction است، یک واحد مستقل که کنشی را در میانای کاربری شما انجام می‌دهد. شما Atoms را بااستفاده از فهرستی از روش‌های تعریف‌شده، مانند findElement() و getElement()، درمعرض دید قرار می‌دهید تا مرورگر را از دیدگاه کاربر هدایت کنید. اما اگر مستقیماً از چارچوب WebDriver استفاده کنید، Atoms باید به‌درستی هماهنگ شود که این کار به منطقی نیاز دارد که بسیار پرحرف است.

در Espresso، کلاس‌های Web و Web.WebInteraction این کد تکراری را می‌پوشانند و حس تعامل با اشیاء WebView را شبیه به Espresso می‌کنند. بنابراین در بافت WebView، از Atoms به‌عنوان جایگزینی برای Espresso سنتی ViewMatchers و ViewActions استفاده می‌شود.

سپس میانای برنامه‌سازی کاربردی بسیار ساده به‌نظر می‌رسد:

کاتلین

onWebView()
    .withElement(Atom)
    .perform(Atom)
    .check(WebAssertion)

جاوا

onWebView()
    .withElement(Atom)
    .perform(Atom)
    .check(WebAssertion);

برای کسب اطلاعات بیشتر، سند Selenium درباره Atoms را بخوانید.

پیاده‌سازی WebView

برای کار با WebView در آزمایش‌های برنامه‌تان، راهنمایی‌های نشان‌داده‌شده در بخش‌های زیر را دنبال کنید.

بسته‌ها

برای گنجاندن Espresso-Web در پروژه‌تان، مراحل زیر را تکمیل کنید:

  1. فایل build.gradle برنامه‌تان را باز کنید. این معمولاً فایل سطح بالا build.gradle نیست، بلکه app/build.gradle است.
  2. خط زیر را در داخل وابستگی‌ها اضافه کنید:

    شیک

        androidTestImplementation 'androidx.test.espresso:espresso-web:3.6.1'
        

    کاتلین

        androidTestImplementation('androidx.test.espresso:espresso-web:3.6.1')
        
  3. Espresso-Web فقط با Espresso نسخه ۲.۲ یا بالاتر و نسخه ۰.۳ یا بالاتر کتابخانه آزمایشی سازگار است، بنابراین حتماً این خطوط را نیز به‌روز کنید:

    شیک

        androidTestImplementation 'androidx.test:runner:1.6.1'
        androidTestImplementation 'androidx.test:rules:1.6.1'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
        

    کاتلین

        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 استفاده می‌کنید، مانند موارد زیر:

کاتلین

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")))

جاوا

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" است پیدا می‌کند و روی آن کلیک می‌کند. سپس ابزار تأیید می‌کند که «وب‌نما» درخواست GET حاوی رشته "navigation_2.html" ارسال می‌کند.

پشتیبانی جاوا اسکریپت

هنگام اجرای آزمایش‌هایتان، سیستم همه تعاملات WebView را بااستفاده از جاوا اسکریپت انجام می‌دهد. بنابراین، برای پشتیبانی از ارزیابی جاوا اسکریپت، WebView تحت آزمایش باید جاوا اسکریپت را فعال کرده باشد.

می‌توانید با فراخوانی forceJavascriptEnabled() به‌عنوان کنش در فعالیتتان تحت آزمایش، جاوا اسکریپت را مجبور به فعال شدن کنید، همان‌طور که در تکه‌کد زیر نشان داده شده است.

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @get:Rule val activityScenarioRule =
        activityScenarioRule<MyWebViewActivity>()

    @Test fun testWebViewInteraction() {
        onWebView().forceJavascriptEnabled()
    }
}

تعامل‌های رایج وب

تعاملات رایج با اشیای Web.WebInteraction شامل موارد زیر است:

  • withElement() به عنصر DOM در WebView ارجاع می‌دهد.

    مثال:

    کاتلین

    onWebView().withElement(findElement(Locator.ID, "teacher"))

    جاوا

    onWebView().withElement(findElement(Locator.ID, "teacher"));
  • withContextualElement() به عنصر DOM محدودشده‌ای در «وب‌نما» ارجاع می‌دهد که نسبت به عنصر DOM دیگری است. باید ابتدا withElement() را فراخوانی کنید تا شیء Web.WebInteraction مرجع (عنصر DOM) را ایجاد کنید.

    مثال:

    کاتلین

    .withElement(findElement(Locator.ID, "teacher"))
        .withContextualElement(findElement(Locator.ID, "person_name"))

    جاوا

    .withElement(findElement(Locator.ID, "teacher"))
        .withContextualElement(findElement(Locator.ID, "person_name"));
  • check() شرطی را ارزیابی می‌کند و مطمئن می‌شود که به true حل می‌شود.

    مثال:

    کاتلین

    onWebView()
        .withElement(findElement(Locator.ID, "teacher"))
        .withContextualElement(findElement(Locator.ID, "person_name"))
        .check(webMatches(getText(), containsString("Socrates")))

    جاوا

    onWebView()
        .withElement(findElement(Locator.ID, "teacher"))
        .withContextualElement(findElement(Locator.ID, "person_name"))
        .check(webMatches(getText(), containsString("Socrates")));
  • perform() کنشی را در WebView اجرا می‌کند، مثلاً کلیک کردن روی یک عنصر.

    مثال:

    کاتلین

    onWebView()
        .withElement(findElement(Locator.ID, "teacher"))
        .perform(webClick())

    جاوا

    onWebView()
        .withElement(findElement(Locator.ID, "teacher"))
        .perform(webClick());
  • reset() «وب‌نما» را به حالت اولیه‌اش برمی‌گرداند. این کار زمانی لازم است که کنش قبلی، مثل کلیک، تغییر پیمایشی ایجاد کند که باعث شود اشیاء ElementReference و WindowReference غیرقابل‌دسترس شوند.

    توجه: اگرچه استفاده از reset() هنگام انجام ادعاها دربرابر گردش‌های کاری چندصفحه‌ای، مانند ارسال فرم، مفید است، آزمایش‌های شما معمولاً باید ازنظر دامنه محدود باشند و روی یک صفحه تمرکز کنند.

    مثال:

    کاتلین

    onWebView()
        .withElement(...)
        .perform(...)
        .reset()

    جاوا

    onWebView()
        .withElement(...)
        .perform(...)
        .reset();

مثال

نمونه زیر آزمایش می‌کند که آیا پس‌از وارد کردن نوشتار در WebView و انتخاب دکمه ارسال، همان نوشتار در عنصر دیگری در همان WebView ظاهر می‌شود یا نه:

کاتلین

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)))
    }
}

جاوا

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 استفاده کنید.