Appium+Python3入門
前言:
Appium 是一個自動化測試開源工具,支持 iOS 平臺和 Android 平臺上的原生應用,web 應用和混合應用。
一、環境配置
1、安裝Node.js
https://nodejs.org/
2、安裝Appium
http://appium.io/
3、安裝Android SDK
http://tools.android-studio.org/index.php/sdk
4、安裝Python-client
pip3 install Appium-Python-Client
5、安裝Appium-client
npm install wd
最後,打開命令行,輸入“appium-doctor”命令,如果出現以下提示,說明你Appium所需要的各項環境都已準備完成。
二、服務關鍵字
Desired Capabilities在啟動session的時候是必須提供的。
Desired Capabilities本質上是以key value字典的方式存放,客戶端將這些鍵值對發給服務端,告訴服務端我們想要怎麽測試。
desired_caps = {}
desired_caps[‘platformName‘] =‘Android‘
desired_caps[‘platformVersion‘] =‘6.0.1‘
desired_caps[‘deviceName‘] =‘e0bbc8b7‘
desired_caps[‘appPackage‘] =‘com.ximalaya.ting.android‘
desired_caps[‘appActivity‘] =‘com.ximalaya.ting.android.host.activity.WelComeActivity‘
desired_caps["unicodeKeyboard"] ="True"
desired_caps["resetKeyboard"] ="True"
self.driver = webdriver.Remote(‘http://127.0.0.1:4723/wd/hub‘, desired_caps)
它告訴appium Server這樣一些事情:
?deviceName:啟動哪種設備,是真機還是模擬器?iPhone Simulator,iPad Simulator,iPhone Retina 4-inch,Android Emulator,Galaxy S4…
?automationName:使用哪種自動化引擎。appium(默認)還是Selendroid。
?platformName:使用哪種移動平臺。iOS, Android, orFirefoxOS。
?platformVersion:指定平臺的系統版本。例如指的Android平臺,版本為5.1。
?appActivity:待測試的app的Activity名字。比如MainActivity、.Settings。註意,原生app的話要在activity前加個”.“。
?appPackage:待測試的app的Java package。比如com.example.android.myApp, com.android.settings。
三、定位控件
1、ID定位
使用方法:driver.find_element_by_id(‘com.android.calculator2:id/formula’)
2、name定位
使用方法:driver.find_element_by_name("9"))
3、class name定位
使用方法:driver.find_element_by_class_name(“android.widget.Button"))
4、XPath定位
使用方法:用class的屬性來替代做標簽的名字。
driver.find_element_by.xpath(“//android.view.ViewGroup/android.widget.Button”)
當果如果出現class相同的情況下可以用控件的屬性值進行區分。
driver.find_element_by_xpath("//android.widget.Button[contains(@text,‘7‘)]").click();
driver.find_element_by_xpath(”//android.widget.Button[contains(@content-desc,’times‘)]").click();
driver.find_element_by_xpath("//android.widget.Button[contains(@text,‘7‘)]").click();
driver.ffind_element_by_xpath("//android.widget.Button[contains(@content-desc,‘equals‘)]").click();
XPath在Appium上的用法依然很強大,有時需要寫更臭更長的定位語法,因為APP上元素的class命令本來就長,再加上多層級,結果可想而知。
5、Accessibility ID定位
使用方法:其實,我們的核心是要找到元素的contentDescription屬性。它就是元素的content-desc。
driver.find_element_by_accessibility_id("plus").click();
6、android uiautomator定位
使用方法:
一個元素的任意屬性都可以通過android uiautomator方法來進行定位,但要保證這種定位方式的唯一性。
driver.find_element_by_android_uiautomator("new UiSelector().text(\”8\")").click();
driver.find_element_by_android_uiautomator("new UiSelector().description(\”plus\")").click();
四、應用操作
1、安裝應用
installApp()
安裝應用到設備中去。需要apk包的路徑。
2、卸載應用
removeApp()
從設備中刪除一個應用。
3、關閉應用
closeApp()
關閉打開的應用,默認關閉當前打開的應用,所以不需要入參。這個方法並非真正的關閉應用,相當於按home鍵將應用置於後臺,可以通過launchApp()再次啟動。
4、啟動應用
launchApp()
啟動應用。你一定很迷惑,不是在初始化的配置信息已經指定了應用,腳本運行的時候就需要啟動應用,為什麽還要有這個方法去啟動應用呢?重新啟動應用也是一個測試點,該方法需要配合closeApp()使用的。
5、檢查應用是否安裝
isAppInstalled()
檢查應用是否已經安裝。需要傳參應用包的名字。返回結果為Ture或False。
6、將應用置於後臺
runAppInBackground()
將當前活躍的應用程序發送到後臺。這個方法需要入參,需要指定應用置於後臺的時長。
7、應用重置
resetApp()
重置當前被測程序到出始化狀態。該方法不需要入參。
五、鍵盤操作
1、SendKeys()方法
driver.find_element_by_name(“Name”).send_keys("jack");
2、PressKeyCode()方法
除此之外,Appium擴展提供了pressKeyCode()方法。該方法Android特有。
發送一個鍵碼的操作。(鍵碼對照表請自行百度,此處不展示了。)
driver.press_keycode(3)//點擊Android的HOME鍵
driver.press_keycode(27)//點擊拍照鍵
3、輸入法問題:
必須使用appium自帶鍵盤,並添加:
desired_caps["unicodeKeyboard"] = "True"
desired_caps["resetKeyboard"] = "True"
六、TouchAction操作
Appium的輔助類,主要針對手勢操作,比如滑動、長按、拖動等。
1、按壓控件press()
開始按壓一個元素或坐標點(x,y)。通過手指按壓手機屏幕的某個位置。
press(WebElement el, int x, int y)
2、長按控件longPress()
開始按壓一個元素或坐標點(x,y)。相比press()方法,longPress()多了一個入參,既然長按,得有按的時間吧。duration以毫秒為單位。1000表示按一秒鐘。其用法與press()方法相同。
longPress(WebElement el, int x, int y, Duration duration)
3、點擊控件tap()
對一個元素或控件執行點擊操作。用法參考press()。
tap(WebElement el, int x, int y)
4、移動moveTo()
將指針(光標)從過去指向指定的元素或點。
movTo(WebElement el, int x, int y)
5、暫停wait()
暫停腳本的執行,單位為毫秒。
action.wait(1000);
七、其他操作
其它操作針對移動設備上特有的一些操作。
1、熄屏
方法:lockDevice()
點擊電源鍵熄滅屏幕。
在iOS設備可以設置熄屏一段時間。Android上面不帶參數,所以熄屏之後就不會再點亮屏幕了。
driver.lockDevice(1000);// iOS
driver.lockDriice();//Android
2、收起鍵盤
方法:hideKeyboard()
收起鍵盤,這個方法很有用,當我們對一個輸入框輸入完成後,需要將鍵盤收起,再切換到一下輸入框進行輸入。
driver.hideKeyboard();//收起鍵盤
3、滑動
方法:swipe()
模擬用戶滑動。將控件或元素從一個位置(x,y)拖動到另一個位置(x,y)。
swipe(int startx, int starty, int endx, int endy, int duration)
* start_x:開始滑動的x坐標。* start_y:開始滑動的y坐標。
* end_x:結束滑動的x坐標。* end_y:結束滑動的y坐標。
* duration:持續時間。
例:driver.swipe(75, 500, 75, 0, 800);
4、截屏
方法:get_screenshot_as_file()
用法:driver.get_screenshot_as_file(‘../screenshot/foo.png‘),參數為保存的圖片路徑和名稱
5、獲取控件各種屬性
方法:get_attribute()
用法: driver.find_element_by_id().get_attribute(name),
name即是左側的標誌(class,package,checkable,checked....),
可獲取的字符串類型:
name(返回content-desc或text)
text(返回text)
className(返回class,只有API=>18才能支持)
resourceId(返回resource-id,只有API=>18才能支持)
八、unittest之斷言
在unittest單元測試框架中,TestCase類提供了一些方法來檢查並報告故障:
>>assertEqual(first, second, msg=None)
判斷first和second的值是否相等,如果不相等則測試失敗,msg用於定義失敗後所拋出的異常信息。
>>assertNotEqual(first, second, msg=None)
測試first和second不相等,如果相等,則測試失敗。
>>assertTure(expr,msg=None)
>>assertFalse(expr,msg=None)
測試expr為Ture(或為False)
>>assertIs(first, second, msg=None)
>>assertIsNot(first, second, msg=None)
測試的first和second是(或不是)相同的對象。
>>assertIsNone(expr, msg=None)
>>assertIsNotNone(expr, msg=None)
測試expr是(或不是)為None
>>assertIn(first, second, msg=None)
>>assertNotIn(first, second, msg=None)
測試first是(或不是)在second中。second包含是否包含first。
九、實例代碼(例子app:喜馬拉雅FM)
import os
import unittest
from appium import webdriver
from time import sleep
# Returns abs path relative to this file and not cwd
PATH =lambdap: os.path.abspath(
os.path.join(os.path.dirname(__file__), p)
)
class Contacts Android Tests(unittest.TestCase):
def setUp(self):
desired_caps = {}
desired_caps[‘platformName‘] =‘Android‘
desired_caps[‘platformVersion‘] =‘6.0.1‘
desired_caps[‘deviceName‘] =‘e0bbc8b7‘
desired_caps[‘appPackage‘] =‘com.ximalaya.ting.android‘
desired_caps[‘appActivity‘] =‘com.ximalaya.ting.android.host.activity.WelComeActivity‘
desired_caps["unicodeKeyboard"] ="True"
desired_caps["resetKeyboard"] ="True"
self.driver = webdriver.Remote(‘http://127.0.0.1:4723/wd/hub‘, desired_caps)
sleep(6)
def tearDown(self):
self.driver.close_app()
self.driver.quit()
deftest_Login(self):
self.driver.find_element_by_id(‘com.ximalaya.ting.android:id/tab_myspace‘).click()
sleep(2)
self.driver.find_element_by_accessibility_id(‘設置‘).click()
sleep(2)
width =self.driver.get_window_size()[‘width‘]
height =self.driver.get_window_size()[‘height‘]
self.driver.swipe(width /2, height *7/8, width /2, height *4/8,1000)
# 不同的手機分辨率不同,所以一個坐標如果用另一個分辨率不同的手機可能位置就有所變化了,為了讓apppium 更好的兼容不同分辨率的設備,
# 在執行滑動前先獲取屏幕的分辨率。
self.driver.find_element_by_id(‘com.ximalaya.ting.android:id/main_tv_login‘).click()
self.driver.find_element_by_id(‘com.ximalaya.ting.android:id/main_username‘).send_keys(‘18500425217‘)
self.driver.find_element_by_id(‘com.ximalaya.ting.android:id/main_password‘).send_keys(‘wj1234‘)
self.driver.find_element_by_id(‘com.ximalaya.ting.android:id/main_login‘).click()
sleep(4)
text =self.driver.find_element_by_id(‘com.ximalaya.ting.android:id/tab_myspace‘).text
self.assertEqual(text,‘我的‘)
deftest_Search(self):
sleep(3)
message =self.driver.find_element_by_id(‘com.ximalaya.ting.android:id/main_item_finding_title‘).text
self.assertEqual(message,‘天天好書‘)
self.driver.find_element_by_accessibility_id("搜索").click()
self.driver.find_element_by_id(‘com.ximalaya.ting.android:id/main_search_et‘).send_keys(‘段子‘)
self.driver.find_element_by_id(‘com.ximalaya.ting.android:id/main_search_button‘).click()
self.driver.get_screenshot_as_file(‘/Users/wangjuan/截圖圖庫/1.jpg‘)
self.driver.press_keycode(4)
self.assertEqual(message,‘天天好書‘)
if__name__ ==‘__main__‘:
suite = unittest.TestLoader().loadTestsFromTestCase(ContactsAndroidTests)
unittest.TextTestRunner(verbosity=2).run(suite)
以上,希望對你有所幫助~~
Appium+Python3入門