zoukankan      html  css  js  c++  java
  • 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, "测试工程师名称元素存在")
    看下报告:

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

    关注微信公众号即可在手机上查阅,并可接收更多测试分享~

  • 相关阅读:
    php解析word,获得文档中的图片
    小程序 图表 antv f2 的使用
    eslint配置大全
    node 操作word excel
    vue-element-admin
    python中字符串前的r什么意思
    python3 三种字符串(无前缀,前缀u,前缀b)与encode()
    Markdown语法
    Python3 字符串前面加u,r,b的含义
    Python os.walk()
  • 原文地址:https://www.cnblogs.com/songzhenhua/p/15755544.html
Copyright © 2011-2022 走看看