เว็บเอสเปรสโซ

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 ที่กำหนดเองกลับมาใช้ซ้ำได้ ซึ่งจะช่วยให้คุณมีความยืดหยุ่นเป็นอย่างมาก โดยเฉพาะ เมื่อเขียนการทดสอบที่คุณวางแผนที่จะเรียกใช้กับทั้งเว็บแอปแบบสแตนด์อโลนและ แอปที่มี UI ของ Android

วิธีการทำงาน

onData() เช่นเดียวกับวิธีของ Espresso WebView การโต้ตอบประกอบด้วย Atom หลายรายการ WebView ใช้ภาษาโปรแกรม Java ร่วมกับบริดจ์ JavaScript เพื่อทำงาน เนื่องจากไม่มีโอกาสที่จะเกิด สภาวะแข่งขันโดยการเปิดเผยข้อมูลจากสภาพแวดล้อม JavaScript (ทุกสิ่งที่ Espresso เห็นในฝั่งที่ใช้ Java เป็นสำเนาที่แยกต่างหาก) ระบบจึงรองรับการส่งคืนข้อมูลจากออบเจ็กต์ Web.WebInteraction อย่างเต็มที่ ซึ่งช่วยให้คุณยืนยันข้อมูลทั้งหมดที่ส่งคืนจากคำขอได้

WebDriver Atom คืออะไร

เฟรมเวิร์ก WebDriver ใช้ Atoms เพื่อค้นหาและจัดการองค์ประกอบของเว็บ โดยใช้โปรแกรม WebDriver ใช้ Atom เพื่ออนุญาตการจัดการเบราว์เซอร์ ในเชิงแนวคิดแล้ว Atom จะคล้ายกับ ViewAction ซึ่งเป็นหน่วยแบบสแตนด์อโลนที่ดำเนินการใน UI คุณจะแสดงอะตอมโดยใช้รายการของเมธอดที่กำหนด เช่น findElement() และ getElement() เพื่อขับเคลื่อนเบราว์เซอร์จากมุมมองของผู้ใช้ อย่างไรก็ตาม หากคุณใช้เฟรมเวิร์ก WebDriver โดยตรง คุณจะต้องจัดระเบียบ Atoms อย่างเหมาะสม ซึ่งต้องใช้ตรรกะที่ค่อนข้างซับซ้อน

ใน Espresso คลาส Web และ Web.WebInteraction จะห่อหุ้มบอยเลอร์เพลตนี้และให้ความรู้สึกเหมือน Espresso เมื่อโต้ตอบกับออบเจ็กต์ WebView ดังนั้นในบริบทของ 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 ไว้ในโปรเจ็กต์ ให้ทำตามขั้นตอนต่อไปนี้

  1. เปิดไฟล์ build.gradle ของแอป โดยปกติแล้วไฟล์นี้จะไม่ใช่ไฟล์ build.gradle ระดับบนสุด แต่จะเป็น app/build.gradle
  2. เพิ่มบรรทัดต่อไปนี้ภายใน dependencies

    Groovy

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

    Kotlin

        androidTestImplementation('androidx.test.espresso:espresso-web:3.6.1')
        
  3. 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() เป็นการดำเนินการในกิจกรรมภายใต้ test ดังที่แสดงใน ข้อมูลโค้ดต่อไปนี้

@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