基於ATX-Server的UI自動化測試框架,可以實現多設備的並行測試,並生成統一的測試報告
前置條件
Android設備需要通過uiautomator2 init 初始化完成,確認可以正常連接 ,或者init 接入atx-server uiautomator版本需 Version: 0.1.3.dev5 及以后
需要依賴的python第三方庫 tinydb、uiautomator2、selenium、jinja2、psutil
相關的基礎鏈接如下
小白入門篇:python uiautomator2 的代碼示例
ATX-uiautomator2 實現 webview 的操作
Public:
- Devices.py 獲取atx-server上特定設備(ATX_Server(object))、或config.ini下devices IP列表的在線設備(get_devices())、有線連接電腦的設備自動連接u2(connect_devices())
- BasePage.py 用於設備的初始化 u2.connect 已經一些公共模塊的封裝
- chromedriver.py 和Ports.py 結合使用,啟動chromedriver以便實現u2的webview操作(目前還沒做到根據設備的chromeversion 啟動指定版本的chromedriver)
- Casestrategy.py 獲取指定路徑下的testcases
- Decorator.py 有[*@*testcase](https://testerhome.com/testcase)、[*@*teststep](https://testerhome.com/teststep)這樣的裝飾器用例執行日志打印、錯誤后的處理(截圖)
- Report.py 對生成的報告的一些操作,備份Testreport的報告到TestReport_backup下、多設備統一報告的生成、報告的文件夾壓縮
- Test_data.py 在執行測試前的測試數據的生成,會在Plubic下生成data.json,測試執行的時候各個設設備更具自己的serial獲取對應的測試數據
- Drivers.py 設備的獲取,初始化准備,測試執行都是在這里完成的
- RunCases.py 存放測試報告/日志/截圖的路徑的生成,以及最終通過HTMLTestRunner來執行用例
- config.ini 一些需要用到的數據,tatx-server地址、測試設備的ip、測試數據等
app UI自動化我們通常框架設置思想是pom模式。
1.將具體的定位方式參數化,實現關鍵字驅動
2.面向業務,將各種通用的業務流程封裝成 可重復使用的函數
3.log生成
4.報告生成
5.測試數據、ddt等
我的這個項目流程做法是:
(1)編寫基礎定位方式封裝成關鍵字
# 基礎定位方法封裝
import os
import random
import time
import uiautomator2 as u2
from uiautomator2 import UiObjectNotFoundError
import re
from Public.chromedriver import ChromeDriver
from Public.Ports import Ports
from Public.ReportPath import ReportPath
class BasePage(object):
@classmethod
def set_driver(cls, dri):
cls.d = u2.connect(dri)
cls.sess = cls.d.session("com.tcl.tclplus")
def get_driver(self):
return self.d, self.sess
def ClickText(self, text):
"""
點擊文本方法操作
"""
self.d(text=text).click()
def ClickResId(self, page):
"""
根據resourceId 進行點擊
"""
self.d(resourceId="com.tcl.tclplus:id/" + page).click()
def ExistsResId(self, page):
"""
判斷resid 是否存在
"""
return self.d(resourceId="com.tcl.tclplus:id/" + page).exists()
def ExistsText(self, text):
"""判斷文本 是否存在"""
return self.d(text=text).exists
def ClickResIdSendKeys(self, *args):
"""
通過ResId 定位並且 輸入內容
"""
self.ClickResId(args[0])
self.d.send_keys(args[1])
def GetTextResID(self, page):
"""
根據RESid 來獲取文本
"""
return self.d(resourceId="com.tcl.tclplus:id/" + page).get_text()
def GetTextXpath(self, text):
"""
獲取文本的xpath
"""
return self.d.xpath(f'//*[@text="{text}"]').get_text()
(2)# 業務方法封裝
# 業務方法封裝
# -*- coding: utf-8 -*-
import random
from Public.Decorator import *
class LoginPage(BasePage):
@teststep
def loginApps(self):
self.ClickText("立即登錄")
time.sleep(1)
if self.ExistsText("確認"):
# if self.ExistsResId("bt_confirm"):
log.i("存在確認,先輸入賬號")
number_list = ["13720140001", "13720140002", "13720140004", "13720140005", "13720140006"]
Count = number_list[random.randint(0, 4)]
log.i(f"取到的賬號為{Count}")
self.ClickResIdSendKeys("ll_phone", Count)
self.ClickText("確認")
time.sleep(3)
if self.ExistsText("賬號密碼登錄"):
self.ClickText("賬號密碼登錄")
self.ClickResIdSendKeys("et_pwd", '123456wqw')
if not self.ExistsResId("cb_login"):
self.d.press("back")
while True:
self.ClickResId("cb_login")
self.ClickText("登錄")
time.sleep(5)
message = self.sess.toast.get_message(wait_timeout=0.5) # 獲取頁面toast
print(f'獲取到的toast為:{message}')
if message == u"請閱讀並同意協議":
continue
else:
break
(3)用例設計並調用
# -*- coding: utf-8 -*-
import unittest
from PageObject.LoginPage import *
from time import sleep
class CreaitPage(unittest.TestCase, BasePage):
@classmethod
@setupclass
def setUpClass(cls):
pass
cls.drivers, cls.sess = BasePage().get_driver()
@classmethod
@teardownclass
def tearDownClass(cls):
pass
@testcase
def test_001_TCL(self):
"""會員權益入口-當前成長值"""
try:
if self.ExistsText("同意並進入"):
self.ClickText("同意並進入")
self.back()
LoginPage().loginApps()
LoginPage().Eor()
sleep(2)
self.ClickResId("tab_lottie_5")
self.assertEqual("綁定設備可提升成長值", self.GetTextResID("tv_right_copy"))
# self.assertEqual("0", self.GetTextResID("tv_score"))
self.assertEqual("成長值", self.GetTextResID("tv_growth_value"))
log.i("會員權益入口校驗成功")
except Exception as e:
raise log.i("會員權益入口校驗失敗")
finally:
pass
@testcase
def test_002_TCL(self):
"""
會員權益-默認展示當前等級
"""
try:
self.ClickResId("iv_vip_enter")
time.sleep(5)
self.assertEqual("會員中心", self.GetTextResID("toolbar_title"))
log.i("會員權益")
except Exception as e:
raise log.i("會員權益")
finally:
pass
其中里面的設備讀取 初始化是之前別人已經封裝好的,我們直接拿來用就行。我們只需要做好 基礎的定位方式封裝成關鍵字 和面向業務 封裝成函數即可。。
網上git項目地址是:http://testerhome.com/topics/21379