上期回顧: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, "測試工程師名稱元素存在")
看下報告:
---------------------------------------------------------------------------------
關注微信公衆號即可在手機上查閱,並可接收更多測試分享~