1. 程式人生 > >【轉】Appium 優化版

【轉】Appium 優化版

Appium 開源分享優化版

之前分享過PageObject+Python+Appium

本版本是對上次版本較大改版,主要解決了:

  • 失敗重連一次(預設一次)可配置多次
  • 基於appium1.7.1 uiautomator2
  • 解決uiautomator2啟動超時
  • 新增檢查點關鍵字,contrary_getval,exceptsl,contrary暫時沒有寫到yml配置檔案中,直接在寫在了page層
    • 檢查點關鍵字contrary:相反檢查點,傳1表示如果檢查元素存在就說明失敗,如刪除後,此元素依然存在
    • 檢查點關鍵字toast: 表示提示框檢查點
    • 檢查點關鍵字contrary_getval: 相反值檢查點,如果對比成功,說明失敗
    • 檢查點關鍵字check: 自定義檢查結果
    • 檢查點關鍵字excepts: 如果為1,表示操作出現異常情況檢查點為成功。如:刪除成功了,此資料不存在則為真
  • 測試報告新增對多臺測試機結果統計(安卓)
  • 適配mac,windows平臺
  • 適配ios測試(簡單除錯通過,後續有機會實際去使用和優化)

程式碼簡要分析

yml測試用例

testinfo:
    - id: test004
      title: 每日新聞卡片瀏覽記錄
      info: 開啟知識
testcase:

    
- element_info: com.huawei.works.knowledge:id/title find_type: ids index: 0 operate_type: get_value info: 獲取每日新聞下對第一條資料 - element_info: com.huawei.works.knowledge:id/title find_type: ids index: 0 operate_type: click is_time: 3 info: 點選每日新聞下對第一條資料
- element_info: h5-scroll find_type: id is_webview: 1 # 切換到webview info: 查詢並獲取詳情頁標題 - element_info: com.huawei.works.knowledge:id/vtb_img_left find_type: id is_webview: 2 # 切換到native operate_type: click info: 點選返回按鈕 - element_info: com.huawei.works.knowledge:id/vtb_img_right2 find_type: id operate_type: click info: 點選首頁歷史記錄按鈕 check: - element_info: com.huawei.works.knowledge:id/browser_knowledge_history_text find_type: ids index: 0 operate_type: get_value info: 查詢是否存在歷史記錄
 

某個用例的page層

from PageObject import Pages


class DayNewHistoryPage:
    '''
    每日新聞瀏覽歷史
    '''

    def __init__(self, kwargs):
        _init = {"driver": kwargs["driver"], "path": kwargs["path"], "device": kwargs["device"],
                 "logTest": kwargs["logTest"], "caseName": kwargs["caseName"]}
        self.page = Pages.PagesObjects(_init)

    def operate(self):  # 操作步驟
        self.page.operate()

    def checkPoint(self):  # 檢查點
        self.page.checkPoint()
 
  • pages再次封裝了一層,主要可以看下重連機制的實現
    • 其實主要用的是launch_app+setupclass,另外一個好處是避免用例依賴,並不會重新啟動一個session
if result is not True and be.RE_CONNECT:
          self.msg = "用例失敗重連過一次,失敗原因:" + self.testInfo[0]["msg"]
          self.logTest.buildStartLine(self.caseName + "_失敗重連")  # 記錄日誌
          self.operateElement.switchToNative()
          self.driver.launch_app()
          self.isOperate = True
          self.get_value = []
          self.is_get = False
          self.operate() # 執行步驟
          result = self.check(kwargs) # 堅持點
          self.testInfo[0]["msg"] = self.msg
      self.operateElement.switchToNative()
 

testcase層呼叫page層

class HomeTest(ParametrizedTestCase):
    # 首頁下拉
    def testAHomeSwipeDown(self):
        app = {}
        app["logTest"] = self.logTest
        app["driver"] = self.driver
        app["path"] = PATH("../yaml/home/HomeSwipeDown.yaml")
        app["device"] = self.devicesName
        app["caseName"] = sys._getframe().f_code.co_name

        page = HomeSwipeDownPage(app)
        page.operate()
        page.checkPoint()

    # banner瀏覽歷史記錄
    def testB0annerHistory(self):
        app = {}
        app["logTest"] = self.logTest
        app["driver"] = self.driver
        app["path"] = PATH("../yaml/home/BannerHistory.yaml")
        app["device"] = self.devicesName
        app["caseName"] = sys._getframe().f_code.co_name
        page = BannerHistoryPage(app)
        page.operate()
        page.checkPoint()

    @classmethod
    def setUpClass(cls):
        super(HomeTest, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        super(HomeTest, cls).tearDownClass()
 

程式碼入口

def runnerCaseApp(devices):
    starttime = datetime.now()
    suite = unittest.TestSuite()
    suite.addTest(ParametrizedTestCase.parametrize(HomeTest, param=devices))
    suite.addTest(ParametrizedTestCase.parametrize(TestWeiQunTest, param=devices))
    unittest.TextTestRunner(verbosity=2).run(suite)
 

比較麻煩case處理

  • 當遇到有些用例比較麻煩,必須單獨寫page 層,比如長按交換空間位置
  • 自定義page層
.....
    def operate(self):
        for item in self.testCase:
            m_s_g = self.msg + "\n" if self.msg != "" else ""

            result = self.operateElement.operate(item, self.testInfo, self.logTest, self.device)
            if not result["result"]:
                msg = "執行過程中失敗,請檢查元素是否存在" + item["element_info"]
                print(msg)
                self.msg = m_s_g + msg
                self.testInfo[0]["msg"] = msg
                self.isOperate = False
                return False

            if item.get("operate_type", "0") == "location":
                app = {}
                web_element = self.driver.find_elements_by_id(item["element_info"])[item["index"]]
                start = web_element.location
                # 獲取控制元件開始位置的座標軸
                app["startX"] = start["x"]
                app["startY"] = start["y"]
                # 獲取控制元件座標軸差
                size1 = web_element.size

                width = size1["width"]
                height = size1["height"]
                # 計算出控制元件結束座標
                endX = width + app["startX"]
                endY = height + app["startY"]

                app["endX"] = endX - 20
                app["endY"] = endY - 60

                self.location.append(app)
                # self.driver.swipe(endX, endY, starty, endY)
            if item.get("operate_type", "0") == be.GET_VALUE:
                self.get_value.append(result["text"])

            if item.get("is_swpie", "0") != "0":
                print(self.location)
                self.driver.swipe(self.location[0]["endX"], self.location[0]["endY"], self.location[1]["endX"], self.location[1]["endY"]+10)

 

 
  • yaml用例 可以自定義一些關鍵字給page用
testinfo:
    - id: test019
      title: 拖動排序知識卡片
      info: 開啟知識
testcase:
    - element_info: com.huawei.works.knowledge:id/vtb_img_right
      find_type: id
      operate_type: click
      info: 點選排序卡片按鈕
    - element_info: com.huawei.works.knowledge:id/my_card_item_name_text
      find_type: ids
      index: 1
      operate_type: get_value
      info: 得到第二個卡片的值
    - element_info: com.huawei.works.knowledge:id/drag_item_image
      find_type: ids
      index: 0
      operate_type: location
      info: 得到第一卡片的座標
    - element_info: com.huawei.works.knowledge:id/drag_item_image
      find_type: ids
      index: 1
      operate_type: location
      is_swpie: 1 # 特殊關鍵字,滑動指令
      info: 得到第二個卡片的座標並拖動
    - element_info: com.huawei.works.knowledge:id/vtb_img_left
      find_type: id
      operate_type: click
      info: 點選返回按鈕
check:
    - element_info: com.huawei.works.knowledge:id/title_txt
      find_type: id
      operate_type: get_value

 

 

其他

  • 順便說下遇到浮動層無法點選
    • 浮動層造成可以識別到元素,觸發了點選卻失效的處理方法是,得到元素座標,然後用adb shell方式去觸發,感興趣的可以看下adb_tap關鍵字的封裝
  • 其他更多優化可以看我的CHANGELOG
  • 開源地址
  • 參考: https://testerhome.com/topics/11720