如何用覆蓋函數的方式,實現你自己的touch?

此文章來源於項目官方公衆號:“AirtestProject”
版權聲明:允許轉載,但轉載必須保留原鏈接;請勿用作商業或者非法用途

1、前言

在使用Airtest進行日常測試工作中,我們有時候想針對某個接口進行功能增強,或者增加一些錯誤處理和重試機制,但是又不想直接修改Airtest源碼,因爲擔心更新Airtest庫就會覆蓋掉源碼的修改。

這個時候,我們更推薦大家使用python覆蓋函數的方式處理,通過覆蓋函數的方式改變函數的行爲是一種常見的編程技巧,既能讓我們的代碼保持靈活性,又避免了直接修改源碼庫。

下文我們將一起來看下覆蓋函數在Airtest框架下的應用小案例.。

2、示例

我們以覆蓋Airtest裏的touch接口爲例,來一起體驗下覆蓋函數的魅力:

2.1 新建一個new_touch腳本文件並導入需要覆蓋的函數

新建一個new_touch腳本文件,並將我們需要增強的函數或某個語句先導入並取一個與原函數不衝突的別名。

from airtest.core.api import touch as old_touch

這一行代碼表示從 airtest.core.api 模塊中導入了touch函數,並將其重命名爲old_touch 。這樣做的目的是保留原有的touch函數,以便在新函數中調用。

2.2 開始定義覆蓋函數

在新建的**new_touch**文件下,可以正常調用舊函數並結合實際場景去增加所需要增強的功能,去實現想要達到的效果。

from airtest.core.api import *
from airtest.core.api import touch as old_touch

def touch(pic):

    try:
	#若打開App後是進入的學習積分界面,即可直接點擊

        old_touch(pic)
        print("進入的是學習積分界面")

    except TargetNotFoundError:
	#若打開App後是進入的App首頁界面,需要先點擊積分

        print("進入的是首頁界面")
        old_touch(Template(r"tpl1712044513750.png", record_pos=(0.267, -1.05), resolution=(1080, 2520)))
        
        print("現在進入了學習積分界面")
        
	#跳轉到對應的學習積分界面後再進行點擊
        old_touch(pic)

2.3 在腳本中導入新函數以覆蓋舊函數

創建一個新的跑測腳本,並將new_touch文件放到與跑測腳本同一文件夾下,使用import導入new_touch文件的touch用法,就可以直接使用我們修改後的touch用法。

# -*- encoding=utf8 -*-
__author__ = "Airtest"

from airtest.core.api import *

from new_touch import touch

#打開進入學習強國App
start_app("cn.xuexi.android")


#嘗試點擊選讀文章任務跳轉
touch(Template(r"tpl1712044077691.png", target_pos=6, record_pos=(-0.006, 0.261), resolution=(1080, 2520)))

在需要使用新的touch函數的腳本中,首先從airtest.core.api導入所有內容,然後從定義了新touch函數的模塊(這裏該模塊名爲new_touch)導入新的touch函數。由於Python的名稱解析是從左到右的,後導入的同名函數會覆蓋先前導入的函數,因此這樣做可以確保新的touch函數覆蓋了原始的 touch 函數。

2.4 最終效果

2.5 覆蓋函數的功能增強

在瞭解完一個簡單的覆蓋函數示例之後,我們可以再來看一個稍微複雜點的小案例,就是利用覆蓋函數,給舊函數增加一些錯誤處理操作或者錯誤log記錄等。依然以Airtest的 touch 接口爲例:

參考代碼如下:

在新的touch函數裏,我們增加了一些錯誤記錄,並截圖錯誤場景,將報錯拋出,在日常點擊的時候可以更精準的去判斷報錯出現的場景以及原因。

from airtest.core.api import *
from airtest.core.api import touch as old_touch
import logging

# 初始化日誌記錄器
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
"""
param target: 點擊目標,可以是圖片(Template)或座標。
param timeout: 超時時間,單位爲秒。
param retry_interval: 重試間隔時間,單位爲秒。
"""

def touch(target, timeout, retry_interval):

    start_time = time.time()  # 記錄開始時間
    while True:
        try:
            # 嘗試點擊目標
            old_touch(target)
            logger.info(f"成功點擊圖片")
            break  # 點擊成功則退出循環
            
        except TargetNotFoundError:
			#計算超時時間
            current_time = time.time()
            elapsed_time = current_time - start_time

            if elapsed_time > timeout:

                # 如果超時,則捕獲異常並記錄錯誤信息
                logger.error(f"在指定的超時時間 {timeout} 秒內未找到目標圖片")

                # 捕獲屏幕截圖以供後續分析
                snapshot(filename=f"error_{current_time}.png")
                raise  # 重新拋出異常,或者可以選擇其他的錯誤處理方式

            else:
                 # 沒有超時,則等待一段時間後重試
                logger.info(f"未找到目標圖片,{retry_interval} 秒後重試...")
                time.sleep(retry_interval)
                continue

        except Exception as e:
            # 捕獲其他可能的異常,並記錄
            current_time = time.time()
            logger.error(f"點擊圖片時發生未知錯誤: {e}")

            # 捕獲屏幕截圖以供後續分析
            snapshot(filename=f"error_{current_time}.png")
            raise  # 重新拋出異常,或者可以選擇其他的錯誤處理方式

調用方式跟剛纔簡單的案例一樣,從 enhanced_touch 文件中 import 新的touch進來,需要注意 importtouch 的語句一定放在 from airtest.core.api import * 之後,確保覆蓋。

# -*- encoding=utf8 -*-
__author__ = "Airtest"

from airtest.core.api import *
from enhanced_touch import touch

auto_setup(__file__)

start_app("cn.xuexi.android")

#調用修改後的touch,並傳入需要識別的圖片、超時時間、重試間隔時間
touch(Template(r"tpl1712113066466.png", record_pos=(0.298, 0.285), resolution=(1080, 2520)), timeout=10, retry_interval=5)

3、小結

函數覆蓋是一種強大的技術,可以在不改變原始代碼的情況下調整、增強或替換現有功能。不過,這種技術也需要謹慎使用,因爲它可能會導致代碼的可讀性和可維護性降低,尤其是在覆蓋的函數邏輯變得複雜時。正確的文檔記錄和清晰的代碼結構對於維護這種類型的代碼至關重要。

我們的樣例僅供參考,不一定適用於所有場合,同時也歡迎大家給我們投稿自己寫的覆蓋函數或封裝函數,我們也會多多分享更多的相關的使用技巧。讓我們一起努力,共同進步~


AirtestIDE下載:airtest.netease.com/
Airtest 教程官網:airtest.doc.io.netease.com/
搭建企業私有云服務:airlab.163.com/b2b

官方答疑 Q 羣:526033840

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章