目錄
安卓主流的自動化測試框架及對比.................................... 2
Appium工具介紹................................................................. 2
環(huán)境搭建.............................................................................. 3
Appium使用實例................................................................. 7
腳本例子............................................................................ 13
當前主流的幾大自動化測試框架及工具有:
Appium仰挣、Robotium震嫉、AndroidTest、Monkey俱济、monkeyRuner、UIAutomator宴霸、MonkeyTalk
其中適用的范圍如下:
?Appium測試 (功能測試僧家,用戶接受度測試,黑盒測試)
Robotium測試 (功能測試赂鲤,用戶接受度測試,黑盒+白盒測試)
?AndroidTest (單元測試柱恤,邏輯測試数初,白盒測試)
?Monkey (壓力測試)
monkeyRuner (功能測試,用戶接受度測試梗顺,黑盒測試)
?UIAutomator - 官方(黑盒測試泡孩,功能測試)
MonkeyTalk (白盒測試,功能測試)
Appium工具介紹
Appium測試相當于黑盒測試寺谤,主要測試UI邏輯正確性仑鸥。同時,也可作為自動化回歸使用变屁。
Appium的優(yōu)勢:
采用Appium時眼俊,無需對被測應用做任何修改;Appium對iOS和Android的原生自動化測試框架進行了封裝粟关,并提供了統(tǒng)一的API(WebDriver API)疮胖,減少了自動化測試代碼的維護工作量;Appium采用Client-Server的架構(gòu)設計闷板,并采用標準的HTTP通信協(xié)議澎灸;Server端負責與iOS/Android原生測試框架交互,無需測試人員關注細節(jié)實現(xiàn)遮晚;Client端基本上可以采用任意主流編程語言編寫測試用例性昭,減少了學習成本。
接下來的文章县遣,以Appium工具+python語言進行介紹糜颠。
Android測試開發(fā)環(huán)境配置:
jdk的安裝與配置(包括環(huán)境變量)
是否安裝成功檢查:
打開cmd,輸入java -version? 顯示版本信息
android sdk安裝與配置(包括環(huán)境變量)
是否安裝成功檢查:
打開cmd艺玲,輸入adb 括蝠,顯示:
連接手機:
手機用數(shù)據(jù)線連電腦,如果安裝了91助手或者360什么的可以先下載手機驅(qū)動饭聚,確認手機能連上忌警,打開cmd輸入:adb devices,當屏幕上出現(xiàn)一串字符,后面顯示devices說明連接成功(出現(xiàn)其它的提示秒梳,得檢查自己的環(huán)境了)
Appium環(huán)境配置:
Python安裝與配置(包括環(huán)境變量)
是否安裝成功檢查:
打開cmd法绵,輸入python,顯示:
安裝node.js
下載官網(wǎng):https://nodejs.org/en/download/23
?? 安裝成功后酪碘,打開cmd朋譬,輸入node –v查看版本號,然后輸入npm:
出現(xiàn)下圖信息后兴垦,表示node.js安裝成功
安裝appium
下載地址:https://bitbucket.org/appium/appium.app/downloads/16
直接雙擊appium-installer.exe文件安裝就好徙赢,桌面會生成一個appium的圖標字柠,啟動后界面顯示如下:
安裝好后,找到這個文件目錄D:\appium\Appium\node_modules\.bin
2.將上面的地址添加到環(huán)境變量path下
3.打卡cmd狡赐,輸入appium-doctor,檢查環(huán)境是否OK窑业,出現(xiàn)如下圖所示,說明環(huán)境OK
Python開發(fā)環(huán)境:
本人使用的是PyCharm 開發(fā)工具枕屉,來編寫代碼常柄,用起來還不錯,推薦搀擂。
Appium使用實例
啟動app
啟動app需要獲取到所測試的包名及l(fā)auncherActivity西潘,獲取的方法很多,比如上一次介紹的當前Activity那個軟件哨颂,可以獲取到喷市;這次介紹一個新的,sdk自帶的工具aapt來獲取它的包名及l(fā)auncherActivity威恼。
aapt即Android Asset
Packaging Tool东抹,在SDK的build-tools目錄下。需將D:\androidsdk\android-sdk-windows\build-tools\24.0.0目錄下找到aapt.exe這個路徑設置環(huán)境變量沃测,添加到path下
打開cmd缭黔,輸入aapt:下圖表示環(huán)境已經(jīng)OK了
獲取apk的包名及l(fā)auncherActivity
打開cmd輸入:aapt dump badging C:\yylc.apk
起始腳本:
# coding=utf-8
from appium import webdriver
import time
import unittest? # 導入unittest框架,此文用到了斷言
import zidian? ? # 導入字典包
desired_caps = {
? ? 'platformName': 'Android',
? ? 'deviceName': '5fce0d83',
? ? 'platformVersion': '6.0.1',
? ? 'appPackage': 'com.test54320',
? ? 'appActivity': 'com.biz.launch.controller.SplashScreenActivity',
? ? # 'unicodeKeyboard': True,
? ? # 'resetKeyboard': True
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
上方的driver的地址蒂破,就是appium設置中server的地址
Appium的相關配置如下(點擊第一個安卓機器人的圖標)
啟動appium(三角形變成正方形馏谨,表示已啟動)
在pycharm上運行腳本(確保手機已連接上電腦)
隨后在手機上會彈出安裝下面兩個軟件的提示,安裝后附迷,桌面上多兩個圖標惧互。那么恭喜你啟動成功!
接著就能看到我們app啟動啦@:袄堋!到此為止稻据,環(huán)境已經(jīng)完全通了艾猜,接下來就是編寫測試用例(腳本)的時候了。
此腳本實現(xiàn)的功能:(從字典中獲取手機號及密碼捻悯,登錄app匆赃,并對結(jié)果頁面進行斷言)該腳本中會有很多我編寫時候的遇到的一些問題所對應的解決辦法的注釋,注釋是精華哈哈=窀俊算柳!別忽略了!
源碼:
# coding=utf-8
from appium import webdriver
import time
import unittest? # 導入unittest框架姓言,此文用到了斷言
import zidian? ? # 導入字典包
desired_caps = {
? ? 'platformName': 'Android',
? ? 'deviceName': '5fce0d83',
? ? 'platformVersion': '6.0.1',
? ? 'appPackage': 'com.test54320',
? ? 'appActivity': 'com.biz.launch.controller.SplashScreenActivity',
? ? # 'unicodeKeyboard': True,
? ? # 'resetKeyboard': True
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
driver.reset()
print('resetApp ok')
time.sleep(5)
# 判斷是否已安裝app
print(driver.is_app_installed("com.bench.test54317"))
time.sleep(1)
print('start')
driver.swipe(700, 700, 50, 700)
print('1')
time.sleep(1)
driver.swipe(700, 700, 50, 700)
print('2')
time.sleep(1)
driver.swipe(700, 700, 50, 700)
print('3')
time.sleep(1)
driver.find_element_by_id("com.bench.test54317:id/view_btn_go").click()
print('splash ok !')
time.sleep(3)
'''
? driver.find_element_by_xpath("http://android.widget.TabHost/android.widget.LinearLayout[contains(@index,3)]").click()
// android.widget.LinearLayout[1]/android.widget.FrameLayout/android.widget.ListView/android.widget.TextView[contains(@index,0)]");
# me = driver.find_element_by_xpath('//android.widget.TabHost/android.widget.LinearLayout[1]')
'''
time.sleep(1)
'''
# find_element_by_xpath中的xpath:/AA/BB[1] 的意思是:選擇AA的第一個BB子元素瞬项,所以下方的腳本意思是:選擇TabHost
# 的第二個LinearLayout的第四個FrameLayout子元素
# me = driver.find_element_by_xpath('//android.widget.TabHost/android.widget.LinearLayout[2]/'
#? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 'android.widget.FrameLayout[4]')----家里電腦ok
'''
'''
id_text = 'resourceId("com.bench.yylc.test54317:id/tv_main_tab").text("資產(chǎn)")'
print(id_text)
driver.find_element_by_android_uiautomator(id_text).click()
'''
me = driver.find_element_by_xpath("http://android.widget.FrameLayout/android.widget.TabHost/"
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "android.widget.LinearLayout/android.widget.RelativeLayout[4]")
print(me)
'''
# me1 = driver.find_element_by_id('com.bench.yylc.test54317:id/home_tab_wrapper')
# print(me1)
'''
me.click()
print('me? ok')
driver.find_element_by_id("com.bench.test54317:id/viewMeAccount").click()
time.sleep(2)
# 輸入手機號? 數(shù)據(jù)字典
'''
創(chuàng)建字典用大括號蔗蹋,數(shù)據(jù)由 key/value 鍵值對組成,keys()方法返回字典中的鍵列表囱淋。
values()返回字典中的值列表纸颜,items()返回(key,value)元組绎橘。
新建一個字典放在lib包中info = zidian.zidian()? 獲取字典數(shù)據(jù)
通過.items()循環(huán)讀取元組(鍵/值對)
通過info['user2']通過唯一的鍵名獲取值
'''
info = zidian.userpwd()
for us in info.items():
? ? print(us)
driver.find_element_by_id("com.bench.test54317:id/yyinput_edittext").send_keys(info['user1'])
print('input phone ok!')
# 點擊下一步
time.sleep(2)
driver.find_element_by_id("com.bench.test54317:id/login_ip_next").click()
time.sleep(2)
# 輸入密碼
driver.find_element_by_id("com.bench.test54317:id/yyinput_edittext").send_keys(info['password1'])
print('input password ok!')
# 確定按鈕
driver.find_element_by_id("com.bench.test54317:id/btn_login_ip_confirm").click()
print('login ok!')
# 對登錄結(jié)果手機號進行斷言
phone = driver.find_element_by_id('com.bench.test54317:id/txt_me_acc_phone').text
print(phone)
# 添加斷言,若手機號不正確唠倦,則打印錯誤信息
# 斷言1
try:
? ? assert '158****0001' in phone
? ? print('login is right1')
except AssertionError as e:
? ? print('login is Error1')
# 斷言2
try:
? ? assert phone == '158****0001'
? ? print('login is right2')
except AssertionError as e:
? ? print('login is Error2')
# 斷言3 (unittest)
'''
1. unittest 本身是一個python的測試框架称鳞,他有他自己的使用規(guī)則;
2. 如果用其中的方法稠鼻,需要引入冈止,方法:
import unittest
class Login(unittest.TestCase):
其中需要引入unittest,然后聲明的類需要繼承它的TestCase才可以訪問其中的方法。
'''
class test_duanyan(unittest.TestCase):
? ? ? ? def test_login(self):
? ? ? ? ? ? self.assertEqual(phone, '158****0001', 'login assert fail!')
? ? ? ? ? ? print('login duanyan3')
# 通過resourceId定位元素
id_text = 'resourceId("com.bench.test54317:id/tv_main_tab").text("資產(chǎn)")'
print(id_text)
driver.find_element_by_android_uiautomator(id_text).click()
time.sleep(2)
# 通過resourceId的 兄弟關系fromParent定位元素
brother = 'resourceId("com.bench.test54317:id/ic_main_tab").fromParent(text("首頁"))'
print(brother)
driver.find_element_by_android_uiautomator(brother).click()
time.sleep(2)
# 通過resourceId的父子關系childSelector定位元素
son = 'resourceId("com.bench.test54317:id/layout_main_tab").childSelector(text("我"))'
print(son)
driver.find_element_by_android_uiautomator(son).click()
time.sleep(2)
# AssertionError(Exception)
# assertThat(el.getText(),equalTo("158****0001"))
# assertThat(phone,equalTo("158****0001"))
print(driver.current_activity)
time.sleep(5)
# 關閉app應用程序
driver.close_app()
print("close ok ")
# 退出 session
driver.quit()
print("quit ok ")
if __name__ == '__main__':
? ? unittest.main()
# coding=utf-8
from appium import webdriver
import time
import unittest? # 導入unittest框架候齿,此文用到了斷言
import zidian? ? # 導入字典包
desired_caps = {
? ? 'platformName': 'Android',
? ? 'deviceName': '5fce0d83',
? ? 'platformVersion': '6.0.1',
? ? 'appPackage': 'com.test54320',
? ? 'appActivity': 'com.biz.launch.controller.SplashScreenActivity',
? ? # 'unicodeKeyboard': True,
? ? # 'resetKeyboard': True
}
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)