1. 程式人生 > >UI自動化測試工具AirTest學習筆記之從touch介面看影象識別

UI自動化測試工具AirTest學習筆記之從touch介面看影象識別

本篇更偏向於原始碼解析,適用於對airtest有一些瞭解,看過入門教程,寫過demo的童鞋,當然初學者也可以在本章的上手環節跳轉到網易官方最快5分鐘教程中學習,因為我覺得那篇教程已經夠好了,就不多寫入門教程了。

目錄

簡介

上手

進階

總結

簡介

Airtest Project是最近非常火的一個ui自動化測試工具,由網易遊戲內部工具團隊開發並開源,獲得谷歌力挺。

AirtestIDE 是一個跨平臺、多端(Windows、web、android、ios、遊戲)的UI自動化測試編輯器。

  • 自動化指令碼錄製、一鍵回放、報告檢視,輕而易舉實現自動化測試流程,自有編輯器一站式解決
  • 支援基於影象識別的
    Airtest
    框架,適用於所有Android和Windows遊戲,會截圖就能寫指令碼
  • 支援基於UI控制元件搜尋的 Poco 框架,適用於Unity3d,Cocos2d與Android、ios App、web
  • 能夠執行在Windows和MacOS上
  • 網易內部已成功應用在數十個專案上,利用 手機叢集 進行大規模自動化測試,手機叢集沒有開源,準備做收費模式吧
  • 使用python編寫,相容2、3,儘量用3吧

上手

官方教程,有演示視訊,有動圖,一目瞭然。環境搭建也相當簡單,基本上安裝好IDE就可以了。

AirTest IDE提供了一站式功能:指令碼開發(錄製、編輯)、裝置管理、執行、回放、結果檢視

相信通過網易的這個上手教程,很多人都能很快就可以把airtest玩起來了。

進階

當我們跟隨著教程寫好一條指令碼,執行起來以後,一起來看看AirTest的大致框架。

首先在AirTest的定義中指令碼檔名的字尾是.air,當我們在IDE中新建一個指令碼檔案

再來到檔案管理中我們可以看到這是一個資料夾。

這裡面有一個跟air指令碼同名的py檔案,其他的png圖片就是在IDE裡截圖,錄製,生成的影象檔案。

開啟這個py檔案來看看:

可以看出在IDE裡顯示的touch(圖片),就是在api裡的一個touch介面,裡面傳入一個Template,這個物件包含了圖片檔案的名稱、錄製時的相對座標(record_pos),解析度(resolution)等,當然還有其他引數:目標位置(target_pos)、rgb匹配(rgb),如果你在IDE裡雙擊圖片就會彈出視窗設定這些詳細引數。

我想影象識別大概就是這樣了:寫指令碼時截下目標圖片(你想要點選的地方),這圖片就跟python指令碼儲存在一起,touch介面傳入這些目標圖片,進行匹配,成功後點擊目標圖片的位置,有興趣的話繼續來看看這個touch介面的原始碼。

@logwrap
def touch(v, times=1, **kwargs):
    """
    Perform the touch action on the device screen

    :param v: target to touch, either a Template instance or absolute coordinates (x, y)
    :param times: how many touches to be performed
    :param kwargs: platform specific `kwargs`, please refer to corresponding docs
    :return: finial position to be clicked
    :platforms: Android, Windows, iOS
    """
    if isinstance(v, Template):
        pos = loop_find(v, timeout=ST.FIND_TIMEOUT)
    else:
        try_log_screen()
        pos = v
    for _ in range(times):
        G.DEVICE.touch(pos, **kwargs)
        time.sleep(0.05)
    delay_after_operation()
    return pos

入參:

  1. v,可以是Template物件(目標截圖),或者是pos(座標)
  2. times,點選次數,預設為1
  3. kwargs,平臺的特殊引數

loop_find(v, timeout=ST.FIND_TIMEOUT)#通過名字大概知道,迴圈查詢這個v,有個超時退出,返回座標點

G.DEVICE.touch(pos, **kwargs)#點選裝置的指定座標點

G.DEVICE應該就是一個當前的裝置,相容android、ios、windows

delay_after_operation#最後點選完以後還等待一下,所以這裡可以配置每步點選的等待時間

所以touch介面的邏輯是:

  1. 如傳入圖片資訊,迴圈查詢匹配出目標圖片所在螢幕的座標點;
  2. 傳入是座標,開始記錄log資訊;
  3. 迴圈點選指定的座標點;
  4. 等待,然後返回目標座標點。

再往下,看一下loop_find這個介面,我想這就是“影象識別”的“核心”部分了,哈哈

@logwrap
def loop_find(query, timeout=ST.FIND_TIMEOUT, threshold=None, interval=0.5, intervalfunc=None):
    """
    Search for image template in the screen until timeout

    Args:
        query: image template to be found in screenshot
        timeout: time interval how long to look for the image template
        threshold: default is None
        interval: sleep interval before next attempt to find the image template
        intervalfunc: function that is executed after unsuccessful attempt to find the image template

    Raises:
        TargetNotFoundError: when image template is not found in screenshot

    Returns:
        TargetNotFoundError if image template not found, otherwise returns the position where the image template has
        been found in screenshot

    """
    G.LOGGING.info("Try finding:\n%s", query)
    start_time = time.time()
    while True:
        screen = G.DEVICE.snapshot(filename=None)

        if screen is None:
            G.LOGGING.warning("Screen is None, may be locked")
        else:
            if threshold:
                query.threshold = threshold
            match_pos = query.match_in(screen)
            if match_pos:
                try_log_screen(screen)
                return match_pos

        if intervalfunc is not None:
            intervalfunc()

        # 超時則raise,未超時則進行下次迴圈:
        if (time.time() - start_time) > timeout:
            try_log_screen(screen)
            raise TargetNotFoundError('Picture %s not found in screen' % query)
        else:
            time.sleep(interval)

入參:

  1. query:要在截圖中查詢的圖片模板(也就是我們寫指令碼截的圖咯)
  2. timeout:最大匹配時間
  3. threshold:預設是None,字面意思是閾值,也就是匹配時的相似度吧,調低點可以更容易匹配上,也更容易匹配錯
  4. interval:迴圈匹配的間隔時間,每次要對裝置截圖傳入進來匹配,中間的等待時間
  5. intervalfunc:傳入一個方法,在匹配失敗時呼叫,也就是可以在介面的外部自定義匹配失敗後的動作

返參:pos:目標圖片在裝置螢幕中的位置

screen = G.DEVICE.snapshot(filename=None)#裝置截圖,所以執行完指令碼以後工程路徑會有很多個截圖檔案,就是這裡產生的。

match_pos = query.match_in(screen)#在裝置截圖中匹配查詢我們傳入的目標圖片

所以這loop_find的邏輯就是:一個迴圈,從裝置中擷取螢幕的圖片,在螢幕圖片上查詢匹配我們的目標圖片,匹配成功則記錄日誌然後返回位置座標,失敗則判斷是否是否有intervalfunc方法需要執行,預設是沒有的,跳過,然後接著繼續迴圈截圖、匹配,直到超時報一個TargetNotFoundError異常出去。

那麼影象的匹配演算法大概就是在這個match_in接口裡了,接著再看一點吧,哈哈

    def match_in(self, screen):
        match_result = self._cv_match(screen)
        G.LOGGING.debug("match result: %s", match_result)
        if not match_result:
            return None
        focus_pos = TargetPos().getXY(match_result, self.target_pos)
        return focus_pos

    @logwrap
    def _cv_match(self, screen):
        # in case image file not exist in current directory:
        image = self._imread()
        image = self._resize_image(image, screen, ST.RESIZE_METHOD)
        ret = None
        for method in ST.CVSTRATEGY:
            if method == "tpl":
                ret = self._try_match(self._find_template, image, screen)
            elif method == "sift":
                ret = self._try_match(self._find_sift_in_predict_area, image, screen)
                if not ret:
                    ret = self._try_match(self._find_sift, image, screen)
            else:
                G.LOGGING.warning("Undefined method in CV_STRATEGY: %s", method)
            if ret:
                break
        return ret

match_in呼叫cv_match進行匹配,然後TargetPos().getXY(match_result, self.target_pos)就是對匹配出來的結果進行處理,在前面講touch的時候有一個引數是target_pos,還有印象嗎?根據教程和文件說明,target_pos是以123456789的數字按九宮格鍵盤排列,分別代表左上角,正上角,右上角,...,右下角。這個getXY就是對這個進行處理的,根據傳入的target_pos對匹配到的座標資訊再做處理返回目標圖片中的不同位置上的座標,預設是返回中心點。

再看cv_match介面,

  1. imread()#根據圖片路徑,將圖片讀取為cv2的圖片處理格式
  2. _resize_image(image, screen, ST.RESIZE_METHOD)#處理圖片尺寸,這裡可以在ST.RESIZE_METHOD自定義縮放規則,預設是用COCOS中的MIN策略
  3. 然後根據CVSTRATEGY(cv策略,應該不同匹配的演算法),有tpl、sift,進行try_match。

其中sift策略中優先對預測的區域進行匹配,也就是用到了再touch介面中傳入的record_pos,終於知道為啥要傳入寫指令碼是截圖的位置了吧。

這個try_match是轉換介面,method,再呼叫method,也就是說匹配的演算法有三個不同的,有興趣可以繼續去看看:

_find_template、_find_sift_in_predict_area、_find_sift這三個介面。

    @staticmethod
    def _try_match(method, *args, **kwargs):
        G.LOGGING.debug("try match with %s" % method.__name__)
        try:
            ret = method(*args, **kwargs)
        except aircv.BaseError as err:
            G.LOGGING.debug(repr(err))
            return None
        else:
            return ret

總結

Airtest的優點

  1. 有個IDE,大大地減少了寫自動化指令碼的難度,搭建環境、寫指令碼,執行指令碼,檢視報告都一站式解決了;
  2. 影象識別,對不能用ui控制元件定位的地方的,使用影象識別來定位,對一些自定義控制元件、H5、小程式、遊戲,都可以支援;
  3. 支援多個終端,使用影象識別的話可以一套程式碼相容android和ios哦,用ui控制元件定位的話需要相容一下。

本篇通過touch介面對airtest的影象識別的原始碼進行了初步的分析,更多影象匹配演算法實現部分,下回分解。

相關推薦

UI自動化測試工具AirTest學習筆記touch介面影象識別

本篇更偏向於原始碼解析,適用於對airtest有一些瞭解,看過入門教程,寫過demo的童鞋,當然初學者也可以在本章的上手環節跳轉到網易官方最快5分鐘教程中學習,因為我覺得那篇教程已經夠好了,就不多寫入門教程了。 目錄 簡介 上手 進階 總結 簡介 Airtest

UI自動化測試工具AirTest學習筆記自定義啟動器

通過本篇,你將瞭解到Airtest的自定義啟動器的運用,以及air指令碼啟動執行的原理,還有批量執行air指令碼的方法。 在用Airtest IDE可以編寫air指令碼,執行指令碼,之後我們會想到那我怎麼一次執行多條指令碼呢?能不能用setup和teardown呢?答案是當

接口測試以及接口測試工具postman學習筆記

get請求 cati sign headers 學習筆記 CA 接口 準備 發送 經常碰到的接口有兩種,webservice接口和http api接口。websercive接口走的是soap協議,請求報文和返回報文都是xml格式的,因此我們需要借助接口測試的工具才能測試;h

Airtest學習筆記裝置管理

> 通過本篇你講了解到Airtest是如何跟安卓裝置互動的,以及多裝置時的多機互動使用。 在之前從Touch介面分析Airtest的影象識別中,在影象識別獲取到目標位置以後,發起點選的操作是通過以下這句: `G.DEVICE.touch(pos, **kwargs)

網易自動化測試工具Airtest初探(二)

上一篇網易自動化測試工具Airtest初探(一),使用了IDE介面方式開發了一條超級簡單的傳送資訊的指令碼。本篇主要是要處理一些邏輯思維稍微複雜一些的,包含一些邏輯判斷,邏輯控制等。 1、先了解下python的一些資料型別和基本語法(個人感覺,其實這些python基礎的東西,稍微知道一下寫法

網易自動化測試工具Airtest初探(一)

Airtest是一款自動化測試工具,主要是基於影象和poco控制元件識別。該工具是由網易遊戲團隊自主研發的工具。 主要有以下優點: 1、上手簡單、低門檻,僅需要了解一點點的python語法,便可以實現指令碼編寫和錄製。 2、執行日誌齊全,還可以一鍵生成報告。 3、最新版本已經支援

redhat7學習筆記零到部署javaweb項目

.com ont 啟用 mir lld fig x86_64 必須 red REDHAT7學習筆記 1. 安裝vmware10 安裝過程略,下載地址:鏈接: https://pan.baidu.com/s/16odKKkRYBxGWDVo1cz_wxA 註意,10以上版本不

Ionic4學習筆記建立到打包

Ionic4學習筆記 Ionic4專案從建立到打包 開發環境 開發工具 專案建立 專案啟動 新增Android平臺 打包成APK APK簽名 完成 Ionic4專案從建立到

Linux學習筆記用QT介面操作板子LED

Linux學習筆記之小目標一:用QT介面操作板子LED 一、目標:用QT繪製一個介面,點選開按鈕,板子LED點亮,點選關按鈕,LED熄滅 二、設計知識點:Linux底層IO驅動,核心程式設計,QT程式設計 三、程式碼部分 1、驅動程式碼 qt-led.c

Nodejs學習筆記bodyParse來看app.use()

前言 最近一直在學習慕課網上的express+mongodb建站課程,老師用了很多模組,以前從未見過,因此慢慢看API文件,調程式碼,試圖把每一個框架都搞懂。 前一篇寫了express一些用法,這一篇也是接上文的,主要是提到了app.use()。 因為在本

Scikit-Learn學習筆記——k-means聚類:影象識別、色彩壓縮

k-means聚類 k-means是一種無監督學習模型——聚類演算法的一種演算法。k-means演算法可以在不帶標籤的多維資料集中尋找確定數量的簇。 最優的聚類結果需要符合一下兩個假設 “簇中心點“是屬於該簇的所有資料點座標的算術平

自動化測試學習筆記第一個代碼

href 自動化 筆記 定義 imp 信息 查找 clas 驅動 實現第一個自動化代碼,控制瀏覽器打開網址,輸入信息並點擊按鈕。 ①導入selenium相關模塊 ②調用selenium的瀏覽器驅動 ③通過驅動訪問網址URL ④通過驅動操作頁面元素 ⑤通過驅動關閉瀏覽器

Python學習筆記(一)——瀏覽器自動化測試工具Selenium

看了網友用Python通過影評來分析電影是好片還是爛片,自己也有了個想法想去分析下百度貼吧的帖子是精品帖子還是水帖子。目前正在熟悉工具的使用。 會用到的庫:Selenium, pandas(資料模型),jieba(分詞器),snownlp(情感分析),worldcloud(

Spark 學習筆記 MONGODB SPARK CONNECTOR 插入性能測試

log font span 技術 strong mongos str server 學習 MONGODB SPARK CONNECTOR 測試數據量: 測試結果: 116萬數據通過4個表的join,從SQL Server查出,耗時1分多。MongoSp

UI自動化測試簡介及Selenium工具的介紹和環境搭建

版本 ebe 需求分析 核心 nis rep color 基於 多語 自動化測試簡介 1.1何為自動化測試?   是把以人為驅動的測試轉化為機器執行的一種過程,它是一種以程序測試程序的過程。換言之,就是以程序實現的方式來代替手工測試。 1.2自動化測試分類   分為功能自動

UI自動化測試(四)AutoIT工具使用和robot對象模擬鍵盤按鍵操作

rop 並保存 cto 右鍵 自動化測試 nqa files 安裝 存在 AutoIT簡介 AutoIt 目前最新是v3版本,這是一個使用類似BASIC腳本語言的免費軟件,它設計用於Windows GUI(圖形用戶界面)中進行自動化操作。它利用模擬鍵盤按鍵,鼠標移動和窗口/

自動化運維工具Ansible學習筆記

playbook ansible 自動化 一、簡介1.1 基本概念: ansible是一個基於python開發的輕量級自動化運維管理工具,可以用來批量執行命令,安裝程序,支持playbook編排。它通過ssh協議來連接主機,去中心化,相對比puppet和saltstack無需安裝客戶即可實現文件

python自動化學習筆記DAY15

als iou inpu 設置 insert return 函數調用 雙擊事件 over JavaScript基礎 1、function對象 函數定義: function 函數名 (參數){ <BR> 函數體;   return 返回值; } 可以使

Spark 學習筆記 Standalone與Yarn啟動和運行時間測試

span ima 上傳 運行 yarn erl 技術分享 word wordcount Standalone與Yarn啟動和運行時間測試: 寫一個簡單的wordcount: 打包上傳運行: Standalone啟動: 運行時間:

python自動化學習筆記DAY19

primary queryset imp 正向查詢 tom 使用 mov orm 復雜 Django-model基礎 表的創建(模型建立) 例1: from django.db import models #書籍 class Book(models.Model):