Airtest API精講之斷言

上期回顧:Airtest之全局變量


以下基於
python3.8;airtestIDE1.2.11;airtest1.2.2;pocoui1.0.83

斷言是每個測試框架都有的,可以理解爲測試點檢驗。Airtest一共有4個斷言API,支持所有Android、iOS、Windows平臺,分別爲:

  • assert_exists:檢驗圖片存在

  • assert_not_exists:檢驗圖片不存在

  • assert_equal:判斷預期值與實際值相等

  • assert_not_equal:判斷預期值與實際值不相等

源碼解析

先來看assert_exists()源碼(不想看源碼的可以直接跳到後面的演示實例):

# 文件位置:your_python_path/site-packages/airtest/core/api.py
def assert_exists(v, msg=""):
    try:
        pos = loop_find(v, timeout=ST.FIND_TIMEOUT, threshold=ST.THRESHOLD_STRICT or v.threshold)
        return pos
    except TargetNotFoundError:
        raise AssertionError("%s does not exist in screen, message: %s" % (v, msg))

參數
v:要判斷的圖片對象
msg:斷言描述信息,會顯示在報告中

源碼很簡單,主要就是調用了loop_find(),這個之前在Airtest源碼分析--圖像識別整體流程講過這裏就不再展開了,只提兩點:
1.timeout=ST.FIND_TIMEOUT,找圖超時時間,默認爲20s。全局變量之前講過,詳情可以看Airtest之全局變量
2.threshold=ST.THRESHOLD_STRICT or v.threshold的意思是:如果配置了全局變量ST.THRESHOLD_STRICT,則取其值,否則取圖片Template實例中的threshold值(後面會在示例中演示)
整體邏輯就是圖片找到返回其座標;如果圖片沒找到,loop_find()會報TargetNotFoundError錯誤,用except接住,換成拋出AssertionError的錯誤。

我們繼續看下assert_not_exists()源碼:

def assert_not_exists(v, msg=""):
    try:
        pos = loop_find(v, timeout=ST.FIND_TIMEOUT_TMP)
        raise AssertionError("%s exists unexpectedly at pos: %s, message: %s" % (v, pos, msg))
    except TargetNotFoundError:
        pass

與assert_exists()正好相反,如果匹配到圖片,則拋出AssertionError的錯誤;如果沒匹配到,loop_find()會報TargetNotFoundError錯誤,用except接住,然後pass使其不報錯。

assert_equal()源碼:

def assert_equal(first, second, msg=""):
    if first != second:
        raise AssertionError("%s and %s are not equal, message: %s" % (first, second, msg))

參數
first:預期值
second:實際值
msg:斷言描述信息,會顯示在報告中

代碼就兩行,很簡單,如果預期值和實際值不一致,拋出AssertionError的錯誤。

assert_not_equal()源碼:

def assert_equal(first, second, msg=""):
    if first == second:
        raise AssertionError("%s and %s are not equal, message: %s" % (first, second, msg))

如果預期值和實際值一致,拋出AssertionError的錯誤。

實例演示

# -*- encoding=utf8 -*-
__author__ = "測試工程師小站"

from airtest.core.api import *

# 通過IDE抓取的公衆號圖標圖片
icon70 = Template(r"tpl1637984484238.png", record_pos=(-0.376, -0.787), resolution=(1080, 2340))
# 複製了上面的圖片,只是把threshold改爲1,實際匹配度不可能達到100%
icon100 = Template(r"tpl1637984484238.png", threshold=1, record_pos=(-0.376, -0.787), resolution=(1080, 2340))
# 斷言默認的threshold=0.7的圖片存在,通過
assert_exists(icon70, "測試工程師小站圖標存在")
# 斷言threshold=1的圖片存在,不通過
assert_exists(icon100, "測試工程師小站圖標相似度1時存在")
# 斷言threshold=1的圖片不存在,通過
assert_not_exists(icon100, "測試工程師小站圖標相似度1時不存在")

執行後,在第2個斷言處失敗,最後一個斷言沒執行,我們看下報告:

第1行:第1個斷言通過
第2行:第2個斷言未通過
第3行:執行失敗,顯示詳細的報錯信息

這樣存在一個問題,報錯後我後面的用例沒執行了,我希望斷言不通過但能繼續執行完,只要加try就行了,如果報錯,就只打印一下報錯信息。修改後的代碼如下:

# -*- encoding=utf8 -*-
__author__ = "測試工程師小站"

from airtest.core.api import *

# 通過IDE抓取的公衆號圖標圖片
icon70 = Template(r"tpl1637984484238.png", record_pos=(-0.376, -0.787), resolution=(1080, 2340))
# 複製了上面的圖片,只是把threshold改爲1,實際匹配度不可能達到100%
icon100 = Template(r"tpl1637984484238.png", threshold=1, record_pos=(-0.376, -0.787), resolution=(1080, 2340))
# 斷言默認的threshold=0.7的圖片存在,通過
assert_exists(icon70, "測試工程師小站圖標存在")
# 斷言threshold=1的圖片存在,不通過
try:
    assert_exists(icon100, "測試工程師小站圖標相似度1時存在")
except Exception as e:
    print(str(e))
# 斷言threshold=1的圖片不存在,通過
assert_not_exists(icon100, "測試工程師小站圖標相似度1時不存在")

再次執行,用例可以全部執行完了,看下報告:

第一個斷言threshold=0.7存在的通過
第二個斷言threshold=1存在的不通過,點擊可以在右側看到詳細的報錯信息

第三個斷言threshold=1不存在的通過


繼續看另2個斷言示例:

# -*- encoding=utf8 -*-
__author__ = "測試工程師小站"

import re
from airtest.core.api import *
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)

# 公衆號名稱,取出來文本爲:測試工程師小站@,不知道爲啥多個@
name = poco("com.tencent.mm:id/a_g").get_text()
# 取@前的文本,即公衆號真正的名稱:測試工程師小站
name = name[:-1]
# 斷言公衆號名稱是:測試工程師小站。通過
assert_equal(name, "測試工程師小站", "公衆號名稱正確")

# 取介紹下面的原創內容,即:129篇原創內容  36位朋友關注 
num_str = poco("com.tencent.mm:id/a5m").get_text()
# 正則查找第一個數值,即129
searchObj = re.search(r'(\d+)', num_str)
count = searchObj.group(1)
# 斷言原創文章不是999,是129嘛,所以通過
assert_not_equal(int(count), 999, "公衆號原創文章數不是999")

運行之後看下報告:
第一個斷言判斷相等,通過

第二個斷言判斷不相等,通過

那麼對於poco框架的執行,有沒有像圖片一樣可以斷言元素存在不存在呢?用assert_equal()、assert_not_equal()也是可以實現的。首先poco本身的wait()當判斷元素存在時返回的是座標,我們需要二次封裝一下,讓其存在返回True,不存在返回False,再用斷言和布爾值對比即可。

# -*- encoding=utf8 -*-
__author__ = "測試工程師小站"

from airtest.core.api import *
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)

def my_wait(poco_obj):
    """
    傳入一個poco對象,判斷是否存在,存在返回True,不存在返回False
    """
    if poco_obj.wait():
        return True
    return False

name = poco("com.tencent.mm:id/a_g")
assert_equal(my_wait(name), True, "測試工程師名稱元素存在")

這樣,執行後,my_wait()返回True,相當於assert_equal(True, True, "測試工程師名稱元素存在")
看下報告:

 

 

 

---------------------------------------------------------------------------------

關注微信公衆號即可在手機上查閱,並可接收更多測試分享~

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