Android自動化測試教程
Appium
Appium簡介
Appium是一個開源測試自動化框架,可用於原生,混合和移動Web應用程序測試。 它使用WebDriver協議驅動iOS,Android和Windows應用程序。
運行原理
Appium的運行原理,和selenium有點類似,都可以理解爲c/s架構。
我們的電腦(c端)上運行自動化測試腳本,調用的是appium的webdriver的接口,appium服務器(s端)接收到我們client上發送過來的命令後,他會將這些命令轉換爲UIautomator認識的命令,然後由UIautomator來在設備上執行自動化。
appium界面
Capabilities配置介紹
Desired capability的功能是配置Appium會話。他們告訴Appium服務器您想要自動化的平臺和應用程序。
Desired Capabilities是一組設置的鍵值對的集合,其中鍵對應設置的名稱,而值對應設置的值。(如:“platformName”: “Android”)Desired Capabilities主要用於通知Appium服務器建立需要的Session。
公用Capability
使用說明
連接手機
首先連續點擊版本號,出現“您已處於開發者模式,無需進行此操作”提示即可
然後打開USB調試功能
手機模擬器用下面其中一個命令連接手機即可
adb connect 127.0.0.1:62025
adb connect 127.0.0.1:62001
adb devices ---查看是否連接 (真機USB連接後會自動連接)
查看元素
打開appium,點擊紅框,配置以下信息。
desired capability參數Json
{
"platformName": "Android",
"platformVersion": "7.1.2",#Android操作系統的版本
"deviceName": "127.0.0.1", #設備名稱
"appPackage": "com.android.settings", #app的包名
"appActivity": ".Settings", #app的activity名稱
"unicodeKeyboard": "True", #使用unicode編碼方式鍵盤發送字符串
"restKeyboard": "True" # 將鍵盤隱藏一起來
}
點擊Start Session
元素捕捉工具Inspector:
在dos界面下輸入以下命令,點擊需要操作的app:
adb logcat -v time | findstr START
腳本中,cmp= 後面的值就是 包名
編寫自動化腳本
from appium import webdriver
from time import sleep,time
desired_caps={
"platformName": "Android", #系統名稱
"platformVersion": "7.1.2", #系統的版本號
"deviceName": "127.0.0.1",#設備名稱
"appPackage": "com.android.settings", #app的包名
"appActivity": ".Settings",#app的activity名稱
"unicodeKeyboard": "True",#使用unicode編碼方式鍵盤發送字符串
"restKeyboard": "True"# 將鍵盤隱藏一起來
}
dr = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_caps)#指定腳本要把內容發送到的地址以及端口
dr.implicitly_wait(30)#隱式等待30秒
元素定位方式
根據id定位
#根據id定位
dr.find_element_by_id(" 222 ").click()#點擊
根據class定位
#根據class定位
dr.find_element_by_class_name('android.widget.TextView').send_keys('123')#輸入信息
根據xpath定位
#根據xpath定位
dr.find_element_by_xpath('//android.widget.TextView[@content-desc="222"] ').click()
UIAutomator定位
UIAutomator元素定位是 Android 系統原生支持的定位方式,雖然與 xpath 類似,但比它更加好用,且支持元素全部屬性定位.定位原理是通過android 自帶的android uiautomator的類庫去查找元素。 Appium元素定位方法其實也是基於Uiautomator來進行封裝的。
使用方法 find_element_by_android_uiautomator() 可以運用UiAutomator元素定位。
UiAutomator提供一下三種方式來定位:
•id定位
•text定位
•class name定位
#根據id定位
test=dr.find_element_by_android_uiautomator\
('new UiSelector().resourceId("com.android.contacts:id/floating_action_button")')
test.click()
#根據test定位
test=dr.find_element_by_android_uiautomator\
('new UiSelector().text("本地保存")')
test.click()
#根據class name定位
test=dr.find_element_by_android_uiautomator\
('new UiSelector().className("android.widget.Button")')
test.click()
定位一組元素
如上圖,兩個輸入框的class屬性都是一樣的,如果要根據class屬性分別來獲取這兩個值,就用使用定位一組元素的方式了,方式和UI界面的定位方式是一樣的。代碼實現如下:
test=dr.find_elements_by_class_name('android.widget.EditText')
#輸入賬號
test[0].send_keys("123456789")
#輸入密碼
test[1].send_keys("1234")
Swipe 兩點之間的滑動操作
我們在使用App的過程中,經常會在屏幕上進行滑動的操作,如,刷新新聞,刷朋友圈等,會做上下滑動的動作;如果是看圖片,就會左右移動。在Appium裏面,我們是用swipe()這個方法來實現這個操作。
語法:
swipe(起始橫座標,起始縱座標,目標橫座標,目標縱座標,時間)
時間,是指滑動使用多長時間,單位爲毫秒。默認爲空,即可以不填
我們可以通過下圖來對滑動進行理解:
from appium import webdriver
from time import sleep
#獲取屏幕的大小
def get_size():
x=dr.get_window_size()['width']
y=dr.get_window_size()['height']
return x,y
size=get_size()
print(size)
sleep(3) #等待3秒
#從下向上滑動
def swipeUp():
size = get_size()
x1 =size[0]*0.5
y1 =size[1]*0.9
y2 =size[1]*0.1
dr.swipe(x1,y1,x1,y2)
swipeUp()
sleep(0.5)#等待0.5秒
#從上向下滑動
def swipDown():
size=get_size()
x1=size[0]*0.5
y1=size[1]*0.1
y2=size[1]*0.9
dr.swipe(x1,y1,x1,y2)
swipDown()
sleep(0.5)#等待0.5秒
#從右向左滑動
def swipeleft():
size = get_size()
x1 =size[0]*0.9
y1 =size[1]*0.1
x2 =size[1]*0.1
dr.swipe(x1,y1,x2,y1)
swipeleft()
sleep(0.5)#等待0.5秒
#從左向右滑動
def swiperight():
size = get_size()
x1 =size[0]*0.1
y1 =size[1]*0.1
x2 =size[1]*0.9
dr.swipe(x1,y1,x2,y1)
swiperight()
sleep(0.5)#等待0.5秒
在滑動時報以下錯誤,修改目標座標到(0.5)或以下參數
演示: x2 =size[1]*0.5
連續滑動
swipe滑動操作,一般是兩點之間的滑動,而實際使用過程中用戶可能要進行一些多點連續滑動操作。如手勢密碼操作,切西瓜等場景。那麼在Appium中該如何模擬這類操作呢?
TouchAction
TouchAction包含一些列操作,比如按壓、長按、點擊、移動、暫停。由這些不同操作可以組成一套動作。使用TochAction需要先導入對應的模塊:
from appium.webdriver.common.touch_action import TouchAction
按壓
方法:press() 按壓一個元素或座標點(x,y)。
press(self, el=None, x=None, y=None)
TouchAction(driver).press(element)
TouchAction(driver).press(x=0,y=308)
長按
方法:long_press()開始按壓一個元素或座標點(x,y)。 相比press()方法,long_press()多了一個入參,就是長按的時間。duration以毫秒爲單位。1000表示按一秒鐘。其用法與press()方法相同。
long_press(self,el=None, x=None, y=None, duration=1000)
點擊
方法:tap() 對一個元素或控件執行點擊操作。用法參考press()。
tap(self,element=None, x=None, y=None, count=1)
移動
方法:move_to() 將指針從上一個點移動到指定的元素或點。
move_to(self,el=None, x=None, y=None)
注意:
移動到目位置有時是算絕對座標點,有時是基於前面一個座標點的偏移量,這個要結合具體App來實踐。
暫停
方法:wait()
wait(self,ms=0)
暫停腳本的執行,單位爲毫秒。
釋放
方法release() ,我們滑動總要停止吧?怎麼停止?就是用這個方法停止。
release(self)
執行
方法:perform() 把要執行的操作發送到Appium服務器,即讓要執行的操作生效。
perform(self)
#連續滑動
from appium import webdriver
from time import sleep
from appium.webdriver.common.touch_action import TouchAction
#獲取屏幕的大小(隨SHOU)
def get_size():
x=dr.get_window_size()['width']
y=dr.get_window_size()['height']
return x,y
size=get_size()
print(size)
#向左滑動
def swipeleft():
size = get_size()
x1 =size[0]*0.9
y1 =size[1]*0.1
x2 =size[1]*0.1
dr.swipe(x1,y1,x2,y1)
# swipeleft()
# swipeleft()
for i in range(3):
swipeleft()
需要打開手機的指針位置來捕捉座標點
#設置手勢密碼
TouchAction(dr).press(x =221 ,y=726 ).wait(1000).\
move_to(x=545 ,y =726 ).wait(1000).\
move_to(x=879 ,y =730 ).wait(1000).\
move_to(x=876 ,y =1057 ).wait(1000).\
move_to(x=535 ,y =1052 ).wait(1000).\
move_to(x=209 ,y =1059 ).wait(1000).\
move_to(x=206 ,y =1393 ).wait(1000).\
move_to(x=543 ,y =1397 ).wait(1000).\
release().perform()
sleep(1)
#dr.close_app()#關閉app
如下圖