基於appium的app自動化測試框架
阿新 • • 發佈:2018-11-15
基於appium框架的app自動化測試 App自動化測試主要難點在於環境的搭建,appium完全是基於selenium進行的擴充套件,所以app測試框架也是基於web測試框架開發的 一、裝置連線 (即構建基礎的測試環境,保證可以驅動裝置進行操作) 0.準備測試環境 1)安裝jdk配置java_home環境變數; 2)安裝Android SDK(安卓軟體開發包)(adb、appt ) 3)安裝nodejs,並通過npm安裝appium 1.獲取app包名appPackage 在cmd命令列中輸入aapt dump badging +apk包目錄
如果提示aapt命令不是內部命令,說明aapt的環境變數配置有問題。
可以直接到android-sdk-windows的安裝目錄下找到aapt程式,在位址列中輸入cmd,然後在執行上面操作,就可以了。 如果執行指令碼出現“no such element: Unable to locate element: {"method":"css selector","selector":"#i1"}
(Session info: webview=39.0.0.0)”原因是不明未解決。一般是在模擬機上會出現這種定位問題,真機沒有。
成功的結果是這樣的,截圖如下:
2.獲取app入口appActivity的值 還是在上面的資訊中往下找找到如下圖的位置,其中name的值就是appActivity的引數值
接下來我們可以啟動appium軟體,直接啟動服務appium-server。
然後,通過以上方法獲取關於app模組資訊,我們可以嘗試寫一下指令碼驅動appium-server來幫我連線到裝置上的app軟體。指令碼命令如下:
指令碼完成後,右鍵執行一下,會發現appium在不停的刷日誌(確保appium和指令碼在同一網段即可,不一定在同一臺電腦) 這樣就證明code-client和appium已經建立了聯絡,然後我們就可以通過寫指令碼命令操作裝置上的軟體了。 如果我們要操作手機上自帶的軟體/功能,沒有辦法獲取apk包怎麼辦呢? 答:進入cmd命令列中輸入adb logcat |findStr START ,然後操作裝置上的功能/軟體,在打出的日誌中查詢第一個START,在其後cmp=後面就是報名appPackage和appActivity
=============================================================================== 二、搭建自動化測試框架 1、整體思路:建立基礎類實現裝置驅動的獲取連線 2、建立頁面類實現頁面中所有的功能元素可被獲取呼叫(程式碼驅動編寫測試用例) 3、建立測試指令碼(測試類),編寫測試方法呼叫測試用例 4、建立服務控制類,通過引數配置的方式連線不同的裝置 5、建立框架的啟動指令碼 具體程式碼如下: 1.建立基礎類實現裝置驅動的獲取連線 1)編寫基礎類,例項化封裝後的appium框架(即Pyapp) 2.建立頁面類實現頁面中所有的功能元素可被獲取呼叫(程式碼驅動編寫測試用例) 2)編寫登入頁面類,實現登入頁面的功能操作
3)編寫單個頁面功能的測試方法
4)逐一編寫測試功能頁面類的相關功能 3.建立測試指令碼(測試類),編寫測試方法呼叫測試用例
4.建立服務控制類,通過引數配置的方式連線不同的裝置 1)新建yml檔案編寫測試裝置的詳細資訊
2)建立服務控制類:服務控制類:appium服務的停止、啟動、監聽;裝置驅動的連線啟動
class Controller(object): #讀取裝置配置檔案中的裝置資訊進行初始化 def __init__(self): # 通過讀取yml檔案獲取 配置資訊 self.conf = Tool().app_data # 拆分包的資訊 self.tester = self.conf.get('tester') # 拆分手機的資訊 self.devices = self.conf.get('devices') # 手機的型別 self.device_type = self.conf.get('device_type') # 唯一手機 self.device = self.devices.get(self.device_type)[0] # 手機名稱 self.deviceName = self.device.get('name') #啟動appium服務,由於我們是程式碼驅動,就不能使用手工開啟appium def start_server(self): device = self.devices.get(self.device_type)[0] ip = device.get('ip') port = device.get('port') deviceName = device.get('deviceName') log = os.path.join(LOGPATH, device.get('name') + '.log') cmd = 'appium -a {ip} -p {port} -U {deviceName} -g {log}'.format( ip=ip, port=port, deviceName=deviceName, log=log) logger.debug('啟動服務的命令:%s'%cmd) # 執行命令 netstat -ano | findstr 9036 -- netstat -nlpt |grep 9036 subprocess.Popen(cmd, stdout=open(log, 'a+'), stderr=subprocess.PIPE, shell=True) #監聽appium服務是否啟動成功 def test_server(self): port = self.devices.get(self.device_type)[0].get('port') while True: #在cmd命令列中執行netstat -ano |findstr 埠,監聽服務是否啟動成功 res = subprocess.getoutput("netstat -ano | findstr %s" % port) if 'LISTENING' in res: logger.debug(res) logger.info("服務啟動成功") break else: time.sleep(3) logger.debug('三秒後重試') return True #開啟手機啟動的連線 def start_driver(self): # 包資訊 和 手機資訊 合併 self.tester.update(self.device) ip = self.tester.get('ip') port = self.tester.get('port') driver = webdriver.Remote('http://{ip}:{port}/wd/hub'.format(ip=ip,port=port),self.tester) # 像對列中put生成的drvier driver_queue.put(driver) #關閉appium服務 def kill_server(self): res = subprocess.getoutput("taskkill /F /IM node.exe /t") logger.debug('kill server :%s'%res) if __name__ == '__main__': contorller = Controller() contorller.kill_server() contorller.start_server() if contorller.test_server(): contorller.start_driver() 5.建立框架的啟動指令碼 主要負責啟動appium服務、啟動裝置驅動連線裝置、執行測試用例、生成測試報告。 詳細程式碼: class Main(object): def __init__(self): self.controller = Controller() self.deviceName = self.controller.deviceName def run(self): self.controller.start_server() if self.controller.test_server(): self.controller.start_driver() suite = unittest.TestSuite() cases = unittest.defaultTestLoader.discover(APPCASE) for case in cases: suite.addTest(case) f = open(APPREPORT.format('{}.html'.format(self.deviceName)), 'wb') runner = HTMLTestRunner(f, verbosity=1, title=u'測試報告', description=u'用例執行情況:') runner.run(suite) f.flush() f.close() if __name__ == '__main__': m = Main() m.run() ============================================================================== 三、編寫測試用例過程中常見的問題: 1.如果執行以上指令碼後,提示“無法與計算機取得聯絡” 一般原因有兩個(1.appium未開啟,2.appium服務和指令碼服務不在一個網段內。) 2. 有時候聯絡兩次執行指令碼會出現“A new session could not be created. Details” 原因是:appium-server和code-client已經連線,無法再去連線。這裡我們可以將appium-server服務關閉然後在新建一個appium-server。在執行指令碼就好了。 主要原因是selenium的版本問題,可是使用set_value()代替send_keys()方法。