首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >看钩!assert/pytest-assume失败后截图

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

作者头像
zx钟
发布2021-09-15 10:40:54
5060
发布2021-09-15 10:40:54
举报
文章被收录于专栏:测试游记测试游记

需求

在使用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
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试游记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求
  • 现状
  • 最终效果
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档