自動化混合應用
Appium 其中一個理念就是你不能為了測試應用而修改應用。為了符合這個方法學,我們可以使用 Selenium 測試傳統 web 應用的方法來測試混合 web 應用 (比如,iOS 應用裡的元素 "UIAWebView") ,這是有可能的。這裡會有一些技術性的複雜,Appium 需要知道你是想測試原生部分呢還是web部分。幸運的是,我們還能遵守 WebDriver 的協議。
在 Appium 測試裡,你需要以下幾步來和 web 頁面交涉:
- 切到 webview 部分
- 呼叫 GET session/:sessionId/contexts
- 這會返回一個我們能訪問的 context 的列表,比如 'NATIVE_APP' 或者 'WEBVIEW_1'
- 用 context 的 id 作為引數,呼叫POST session/:sessionId/context方法,切換到 webview 中去。
- (這會將你的 Appium session 放入一個模式, 在這個模式下,所有的命令都會被解釋成自動化 web 檢視而不是原生的部分。比如,當你執行 getElementByTagName,它會在 web 檢視的 DOM 上操作,而不是返回 UIAElements。當然,一個 Webdriver 的方法只能在一個上下文中有意義,所以如果在錯誤的上下文,你會收到錯誤資訊。)
- 如果你想停止 web 檢視的自動化,回到原生部分,你可以簡單地用
context
// 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