Appium 是一個自動化測試開源工具,支持 iOS 平臺和 Android 平臺上的原生應用,web 應用和混合應用。php
一、安裝Node.jsnode
https://nodejs.org/android
二、安裝Appiumweb
http://appium.io/ npm
三、安裝Android SDKandroid-studio
http://tools.android-studio.org/index.php/sdksession
四、安裝Python-clientapp
pip3 install Appium-Python-Client框架
五、安裝Appium-clientide
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。
一、ID定位
使用方法:driver.find_element_by_id(‘com.android.calculator2:id/formula’)
二、name定位
使用方法:driver.find_element_by_name("9"))
三、class name定位
使用方法:driver.find_element_by_class_name(「android.widget.Button"))
四、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命令原本就長,再加上多層級,結果可想而知。
五、Accessibility ID定位
使用方法:其實,咱們的核心是要找到元素的contentDescription屬性。它就是元素的content-desc。
driver.find_element_by_accessibility_id("plus").click();
六、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();
一、安裝應用
installApp()
安裝應用到設備中去。須要apk包的路徑。
二、卸載應用
removeApp()
從設備中刪除一個應用。
三、關閉應用
closeApp()
關閉打開的應用,默認關閉當前打開的應用,因此不須要入參。這個方法並不是真正的關閉應用,至關於按home鍵將應用置於後臺,能夠經過launchApp()再次啓動。
四、啓動應用
launchApp()
啓動應用。你必定很迷惑,不是在初始化的配置信息已經指定了應用,腳本運行的時候就須要啓動應用,爲何還要有這個方法去啓動應用呢?從新啓動應用也是一個測試點,該方法須要配合closeApp()使用的。
五、檢查應用是否安裝
isAppInstalled()
檢查應用是否已經安裝。須要傳參應用包的名字。返回結果爲Ture或False。
六、將應用置於後臺
runAppInBackground()
將當前活躍的應用程序發送到後臺。這個方法須要入參,須要指定應用置於後臺的時長。
七、應用重置
resetApp()
重置當前被測程序到出始化狀態。該方法不須要入參。
一、SendKeys()方法
driver.find_element_by_name(「Name」).send_keys("jack");
二、PressKeyCode()方法
除此以外,Appium擴展提供了pressKeyCode()方法。該方法Android特有。
發送一個鍵碼的操做。(鍵碼對照表請自行百度,此處不展現了。)
driver.press_keycode(3)//點擊Android的HOME鍵
driver.press_keycode(27)//點擊拍照鍵
三、輸入法問題:
必須使用appium自帶鍵盤,並添加:
desired_caps["unicodeKeyboard"] = "True"
desired_caps["resetKeyboard"] = "True"
Appium的輔助類,主要針對手勢操做,好比滑動、長按、拖動等。
一、按壓控件press()
開始按壓一個元素或座標點(x,y)。經過手指按壓手機屏幕的某個位置。
press(WebElement el, int x, int y)
二、長按控件longPress()
開始按壓一個元素或座標點(x,y)。相比press()方法,longPress()多了一個入參,既然長按,得有按的時間吧。duration以毫秒爲單位。1000表示按一秒鐘。其用法與press()方法相同。
longPress(WebElement el, int x, int y, Duration duration)
三、點擊控件tap()
對一個元素或控件執行點擊操做。用法參考press()。
tap(WebElement el, int x, int y)
四、移動moveTo()
將指針(光標)從過去指向指定的元素或點。
movTo(WebElement el, int x, int y)
五、暫停wait()
暫停腳本的執行,單位爲毫秒。
action.wait(1000);
其它操做針對移動設備上特有的一些操做。
一、熄屏
方法:lockDevice()
點擊電源鍵熄滅屏幕。
在iOS設備能夠設置熄屏一段時間。Android上面不帶參數,因此熄屏以後就不會再點亮屏幕了。
driver.lockDevice(1000);// iOS
driver.lockDriice();//Android
二、收起鍵盤
方法:hideKeyboard()
收起鍵盤,這個方法頗有用,當咱們對一個輸入框輸入完成後,須要將鍵盤收起,再切換到一下輸入框進行輸入。
driver.hideKeyboard();//收起鍵盤
三、滑動
方法: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);
四、截屏
方法:get_screenshot_as_file()
用法:driver.get_screenshot_as_file('../screenshot/foo.png'),參數爲保存的圖片路徑和名稱
五、獲取控件各類屬性
方法: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單元測試框架中,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。
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)
以上,但願對你有所幫助~~