Espresso Web

Espresso-Web 是與 Android WebView UI 元件搭配使用的進入點。 Espresso-Web 重複使用熱門 WebDriver API 中的 Atom,以檢查及控制 WebView 的行為。

使用 Espresso-Web 的時機

使用 Espresso-Web 測試您的混合型應用程式,特別是將 應用程式的原生 UI 元件及其 WebView 使用者介面元件您可以將 Espresso-Web API 與其他 Espresso API,與 WebView 物件內的網頁元素完全互動。

您只需要測試 WebView 本身,不需要測試 請考慮應用程式中 WebView 和原生元件之間的互動 使用 WebDriver 等架構撰寫一般網路測試。如果您使用網頁測試架構,則不必 您需要使用 Android 裝置或 Java 虛擬機器,以便進行測試 更快速可靠地執行儘管如此,Espresso-Web 的 和您自訂的 WebDriver 原稿,這種做法較具彈性 因此編寫要針對獨立網頁應用程式和 包括 Android UI 的應用程式

運作方式

與 Espresso 的 onData() 類似 方法,WebView 互動包含多個 Atom。 WebView 互動會使用 Java 程式設計語言和 以便完成其工作。因為幾乎沒有機會 競爭狀況,方法是從 JavaScript 環境公開資料, Espresso 是以 Java 為基礎的端所呈現的獨立副本,也就是從 Web.WebInteraction敬上 物件受到完整支援,可讓您驗證從 要求。

什麼是 WebDriver Atom?

WebDriver 架構使用 Atoms 來尋找和操控網頁元素 編寫程式WebDriver 會利用 Atom 來控制瀏覽器。一個 Atom 在概念上與 ViewAction, 在您 UI 中執行動作的單元。您可以使用 並定義 findElement()getElement() 等方法 從使用者的角度來看不過,如果您使用 WebDriver 原始架構,Atoms 必須妥善調度 較為繁複

在 Espresso 中,Web 類別 和 Web.WebInteraction 納入這個樣板,打造類似 Espresso 的感受,與 WebView 互動 如需儲存大量結構化物件 建議使用 Cloud Bigtable因此,在 WebView 的情況下,Atoms 會做為 改成傳統 Espresso ViewMatchersViewActions

接著,這個 API 看起來相當簡單:

Kotlin

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

Java

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

如需更多資訊,請參閱 Selenium 的 Atom 說明文件

實作 WebView

請遵循下列各節中的指引,即可開始使用 WebView

套件

如要在專案中納入 Espresso-Web,請完成下列步驟:

  1. 開啟應用程式的 build.gradle 檔案。這通常不是 頂層 build.gradle 檔案,但 app/build.gradle
  2. 在依附元件中加入下列程式碼:

    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() 是透過以下程式語言在 Android 環境中使用 WebView 時的主要進入點: 「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 找到 ID 為 "link_2" 且 而非一網打盡接著,工具會驗證 WebView 是否傳送 GET 要求 ,其中包含 "navigation_2.html" 字串。

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() 參照 WebView 中的 DOM 元素。

    例子:

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

其他資源

如要進一步瞭解如何在 Android 測試中使用 Espresso-Web,請參閱 資源。

範例