appium是開源的移動端自動化測試框架,可以測試ios,android應用。appium讓移動端自動化測試不必限定在某種語言和某個具體的框架;也就是說任何人都可以使用自己最熟悉最順手的語言以及框架來做移動端自動化測試,支持java/python/Ruby等語言。
appium的技術架構
OS: Apple's UIAutomation
Android 4.2+: Google's UiAutomator
Android 2.3+: Google's Instrumentation
appium原理
Client/Server Architecture
appium的核心其實是一個暴露了一系列REST API的server。
這個server的功能其實很簡單:監聽一個端口,然后接收由client發送來的command。翻譯這些command,把這些command轉成移動設備可以理解的形式發送給移動設備,然后移動設備執行完這些command后把執行結果返回給appium server,appium server再把執行結果返回給client。
在這里client其實就是發起command的設備,一般來說就是我們代碼執行的機器,執行appium測試代碼的機器。狹義點理解,可以把client理解成是代碼,這些代碼可以是java/ruby/python/js的,只要它實現了webdriver標准協議就可以。
這樣的設計思想帶來了一些好處:
Session
session就是一個會話,在webdriver/appium,你的所有工作永遠都是在session start后才可以進行的。一般來說,通過POST /session這個URL,然后傳入Desired Capabilities就可以開啟session了。
開啟session后,會返回一個全局唯一的session id,以后幾乎所有的請求都必須帶上這個session id,因為這個seesion id代表了你所打開的瀏覽器或者是移動設備的模擬器。
進一步思考一下,由於session id是全局唯一,那么在同一台機器上啟動多個session就變成了可能,這也就是selenium gird所依賴的具體理論根據。
Appium Server
這就是每次我們在命令行用appium命令打開的東西。
Appium Clients
由於原生的webdriver api是為web端設計的,因此在移動端用起來會有點不倫不類。appium官方提供了一套appium client,涵蓋多種語言ruby/java/python。在測試的時候,一般要使用這些client庫去替換原生的webdriver庫。這實際上不是替換,算是client對原生webdriver進行了一些移動端的擴展,加入了一些方便的方法,比如swipe之類,appium client讓我們可以更方便的寫出可讀性更好的測試用例。
Desired Capabilities
Desired Capabilities攜帶了一些配置信息。從本質上講,這個東東是key-value形式的對象。你可以理解成是java里的map,python里的字典,ruby里的hash以及js里的json對象。實際上Desired Capabilities在傳輸時就是json對象。
Desired Capabilities最重要的作用是告訴server本次測試的上下文。這次是要進行瀏覽器測試還是移動端測試?如果是移動端測試的話是測試android還是ios,如果測試android的話那么我們要測試哪個app? server的這些疑問Desired Capabilities都必須給予解答,否則server不買賬,自然就無法完成移動app或者是瀏覽器的啟動。
python里的Desired Capabilities配置:
from appium import webdriver desired_caps = {} desired_caps['platformName'] = 'Android'
desired_caps['deviceName'] = 'myAndroid'
desired_caps['appPackage'] = 'com.android.calculator2'
desired_caps['appActivity'] = '.Calculator' driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
以上參考http://www.yangyanxing.com/article/1266.html
appium安裝
1.先安裝node.js。官網下載安裝:https://nodejs.org/
2.安裝appium。
1)可以通過CMD窗口,執行npm install -g appium 命令來安裝Appium
2)也可以直接去appium官網下載安裝包來安裝。但是可能下不下來,這里給出一個百度網盤的下載鏈接:http://pan.baidu.com/s/1jGvAISu
安裝完成后,將appium可執行文件所在的目錄添加到環境變量Path。再通過命令行可以啟動appium:
$appium --session-override --no-reset
--no-reset 即可避免執行用例的時候再次安裝app,--session-override 不必每次重啟session
appium client安裝
主要講一下python,推薦在線安裝:
$pip install Appium-Python-Client
appium API的使用
以python為例,直接上代碼
#coding:gbk from appium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.touch_actions import TouchActions desired_caps = {} desired_caps['platformName'] = 'Android' desired_caps['deviceName'] = 'myphone' desired_caps['appPackage'] = 'com.android.calculator2' desired_caps['appActivity'] = '.Calculator' driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) element_id = "digit1" element_text = "2" #用find_element_by_id方式查找element,等待20s try: elm = WebDriverWait(driver, timeout=20, poll_frequency=0.5).until(lambda x: x.find_element_by_id(element_id)) except Exception, e: print e #找到elm后點擊 if elm: elm.click() #通過控件id獲取控件text Text = elm.get_attribute("text") if Text: print Text #用find_element_by_name方式查找element,等待20s try: elm1 = WebDriverWait(driver, timeout=20, poll_frequency=0.5).until(lambda x: x.find_element_by_name(element_text)) except Exception, e: print e #獲得當前activity act = driver.current_activity #通過TouchActions類繪制折線 try: grid = WebDriverWait(driver, timeout=20, poll_frequency=0.5).until(lambda x: x.find_element_by_id('panelswitch')) except Exception, e: print e #控件grid的大小和位置 width = grid.size['width'] height = grid.size['height'] x1 = grid.location['x'] y1 = grid.location['y'] #繪制折線 action = TouchActions(driver) action.tap_and_hold(x1+width/8,y1+height/8).move(x1+width/8+width/3.4, y1+height/8).move(x1+width/8+width/3.4,y1+height/8+height*0.8).release(x1+width/8+width/3.4,y1+height/8+height*0.8) action.perform() #發送鍵盤事件,4表示返回鍵,更多見http://blog.csdn.net/wxlinwzl/article/details/41775333 driver.keyevent(4) #獲取屏幕長寬 width = driver.get_window_size()['width'] height = driver.get_window_size()['height'] #滑動 driver.swipe(width/2, 10, width/2, height/2)
