看钩!assert/pytest-assume失败后截图

需求

在使用pytest-assume的时候,它会等待测试函数执行结束才会抛出错误,这样我们可以执行更多,在最终的时候统一查看错误。

但是在进行ui自动化测试的时候,我需要在错误出现的时候就进行截图。

现状

之前使用pytestassue进行测试脚本编写的时候,使用了pytest_runtest_makereport钩子函数就行了

通过测试执行状态判断再进行失败截图

@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
    """
    pytest 失败后执行
    :param item: 测试用例
    :param call: 测试步骤
    :return:
    """
    out = yield
    result = out.get_result()
    logger.info(f"测试报告:{result}")
    logger.info(f"执行耗时:{call.duration}")
    if result.outcome in ['failed', 'error']:
        for k, v in item.funcargs.items():
            if hasattr(v, 'driver'):
                attach_png(f'{TEST_PIC}/{int(time.time())}.png', "失败截图", v)
                break

这个钩子传入了一个item对象,通过简单的调试就可以发现,我们需要的页面操作对象也在里面,所以我们可以方便的进行截图。

所以,理所当然的打开pytest-assume的源码看一下,有没有相关的钩子可以使用

def pytest_assume_fail(lineno, entry):
    """
    Hook to manipulate user-defined data in-case of assumption failure.
    lineno: Line in the code from where asumption failed.
    entry: The assumption failure message generated from assume() call
    """
    pass

找到了pytest_assume_fail,这下离我们失败截图这个需求,就差一步了,也就是拿到页面操作对象。

但是调试一下我们就可以发现,它给我们的两个参数linenoentry

我们写一个简单的测试脚本查看一下

import pytest

def test_a():
    pytest.assume(0, "错了")

lineno:失败的行数

11

entry:失败的内容

test_1.py:11: AssumptionFailure
>>    pytest.assume(0, "错了1")
AssertionError: 错了1
assert 0
调试1

测试函数中页面操作对象会通过fixture的方式传入,所以在流程中它肯定是能找到的

这时就比较容易想到常用的两个方法

  • locals()

  • globals()

然而,找了一圈还是没找到页面操作的对象

这时候我在pytest-assume中发现了

(frame, filename, line, funcname, contextlist) = inspect.stack()[stack_level][0:5]
frame

这样,就找到了这个页面操作对象!

现在就是仿照一下这段代码了[[inspect -检查对象#使用inspect查看调用堆栈]]

import inspect
inspect.stack()

我们查看一下效果

调试2

它会依次打印我们的执行堆栈信息

我们根据测试脚本的名字,就可以很方便的找到页面对象了!

最终效果

  1. 确定当前测试脚本位置

  2. 遍历调用堆栈列表

  3. 根据脚本名称找到对应列表索引

  4. 查看是否有页面操作对象

  5. 失败截图并跳出

def pytest_assume_fail(lineno, entry):
    file_name = os.getcwd() + '/test_'
    for i in inspect.stack():
        if file_name in i.filename:
            try:
                for k, v in i.frame.f_locals.items():
                    if hasattr(v, 'driver'):
                        attach_png(f'{TEST_PIC}/{int(time.time())}.png', "失败截图", v)
                        break
            except Exception:
                pass
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值