1. 程式人生 > >自動化混合應用

自動化混合應用

Appium 其中一個理念就是你不能為了測試應用而修改應用。為了符合這個方法學,我們可以使用 Selenium 測試傳統 web 應用的方法來測試混合 web 應用 (比如,iOS 應用裡的元素 "UIAWebView") ,這是有可能的。這裡會有一些技術性的複雜,Appium 需要知道你是想測試原生部分呢還是web部分。幸運的是,我們還能遵守 WebDriver 的協議。

在 Appium 測試裡,你需要以下幾步來和 web 頁面交涉:

  1. 切到 webview 部分
  2. 呼叫 GET session/:sessionId/contexts
  3. 這會返回一個我們能訪問的 context 的列表,比如 'NATIVE_APP' 或者 'WEBVIEW_1'
  4. 用 context 的 id 作為引數,呼叫POST session/:sessionId/context方法,切換到 webview 中去。
  5. (這會將你的 Appium session 放入一個模式, 在這個模式下,所有的命令都會被解釋成自動化 web 檢視而不是原生的部分。比如,當你執行 getElementByTagName,它會在 web 檢視的 DOM 上操作,而不是返回 UIAElements。當然,一個 Webdriver 的方法只能在一個上下文中有意義,所以如果在錯誤的上下文,你會收到錯誤資訊。)
  6. 如果你想停止 web 檢視的自動化,回到原生部分,你可以簡單地用 context
     呼叫來離開 web 層,引數傳原生 context id 即可。
// javascript
// 假定你已經初始化driver
driver
    .contexts().then(function (contexts) { // 獲取view列表,返回陣列格式: ["NATIVE_APP","WEBVIEW_1"]
        return driver.context(contexts[1]); // 選擇 webview context
    })

    // 執行web測試
    .elementsByCss('.green_button').click()

    .context('NATIVE_APP') // leave webview context

    //把native操作放這裡
    
    .quit() // 退出driver
// java
// 假定我們設定了capabilities
driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);

Set<String> contextNames = driver.getContextHandles();
for (String contextName : contextNames) {
    System.out.println(contextNames); //輸出 NATIVE_APP \n WEBVIEW_1
}
driver.context(contextNames.toArray()[1]); // 設定當前 context 為 WEBVIEW_1

//執行web測試
String myText = driver.findElement(By.cssSelector(".green_button")).click();

driver.context("NATIVE_APP");

//如果需要此次放置native測試指令碼

driver.quit();
# ruby
# 假定我們設定了capabilities
@driver = Selenium::WebDriver.for(:remote, :desired_capabilities => capabilities, :url => SERVER_URL)

# I switch to the last context because its always the webview in our case, in other cases you may need to specify a context
# View the appium logs while running @driver.contexts to figure out which context is the one you want and find the associated ID
# Then switch to it using @driver.switch_to.context("WEBVIEW_6")

Given(/^I switch to webview$/) do
    webview = @driver.contexts.last
    @driver.switch_to.context(webview)
end

Given(/^I switch out of webview$/) do
    @driver.switch_to.context(@driver.contexts.first)
end

# Now you can use CSS to select an element inside your webview

And(/^I click a webview button $/) do
    @driver.find_element(:css, ".green_button").click
end
# python
# assuming we have an initialized `driver` object for an app

# switch to webview
webview = driver.contexts.last
driver.switch_to.context(webview)

# do some webby stuff
driver.find_element(:css, ".green_button").click

# switch back to native view
driver.switch_to.context(driver.contexts.first)

# do more native testing if we want

driver.quit()
// php
// assuming we have an initialized `driver` object in an AppiumTestCase

public function testThings()
{
        $expected_contexts = array(
                0 => 'NATIVE_APP',
                1 => 'WEBVIEW_1'
        );

        $contexts = $this->contexts();
        $this->assertEquals($expected_contexts, $contexts);

        $this->context($contexts[1]);
        $context = $this->context();
        $this->assertEquals('WEBVIEW_1', $context);

        // do webby stuff

        $this->context('NATIVE_APP');

        // do mobile stuff
}

自動化 Android 的混合應用

Appium 通過 Chromedriver 內建混合應用支援。Appium 也可以使用 Selendroid 支援 4.4 之前的裝置的 webview 測試。(你需要在 desired capability 裡指定 "device": "selendroid")。

請確保 setWebContentsDebuggingEnabled 設定為 true。具體見remote debugging docs.

一旦你設定了 desired capabilities,開始一個 appium 會話,遵循上面的教程。

自動化 iOS 混合應用

Appium 使用 remote debugger 建立和 webview 的互動連線。當在模擬器上執行下面例子的時候,我們可以直接建立連線,因為模擬器和 appium 伺服器在同一臺機器上。

一旦你設定了 desired capabilities,開始一個 appium 會話,遵循上面的教程。

在 iOS 真機上執行

當在真機上執行用例時,appium 無法直接訪問 web 檢視,所以我們需要通過 USB 線纜來建立連線。我們使用 ios-webkit-debugger-proxy建立連線。

如何安裝和使用 iOS webkit debug proxy,請參考 iOS webkit debug proxy