• pytest的Hook函数详解


    Hook函数的定义
    Hook函数又称为钩子函数,它的作用可以理解成钩住自己喜欢的东西(在window中,喜欢的东西可理解为消息),然后对自己喜欢的东西单独做处理

    如:我写了一个window程序,在程序中我写了一段代码(调用window的api来实现钩子),这段代码被系统通过系统调用,把其挂入系统中,然后我就可以对我感兴趣的消息进行处理

    我写的这段代码包含有一个回调函数,当有我喜欢的消息发出时,这个回调函数就会执行,所以说,钩子就是指的回调函数

    pytest的Hook函数,修改pytest-html报告
    可以修改自定义修改pytest-html报告,修改方法如下:
    (1)在项目根目录添加confest.py

    (2)在confest.py通过为标题行实现自定义钩子函数来修改列,下面的示例在conftest.py脚本中使用测试函数docstring添加描述(Description)列,添加可排序时间(Time)列,并删除链接(Link)列:

    from datetime import datetime
    from py.xml import html
    import pytest
    
    @pytest.mark.optionalhook
    def pytest_html_results_table_header(cells):
    cells.insert(2, html.th('Description'))
    cells.insert(1, html.th('Time', class_='sortable time', col='time'))
    cells.pop() #删除最后links列的内容
    
    @pytest.mark.optionalhook
    def pytest_html_results_table_row(report, cells):
    cells.insert(2, html.td(report.description))
    cells.insert(1, html.td(datetime.utcnow(), class_='col-time'))
    cells.pop() #删除最后links列的内容
    
    @pytest.mark.hookwrapper #也可以用@pytest.hookimpl(hookwrapper=True) 两者作用相同
    def pytest_runtest_makereport(item, call): #此钩子函数在setup(初始化的操作),call(测试用例执行时),teardown(测试用例执行完毕后的处理)都会执行一次
    outcome = yield
    report = outcome.get_result()
    report.description = str(item.function.__doc__)


    参考链接:pytest文档20-pytest-html报告优化(添加Description)
    https://www.cnblogs.com/yoyoketang/p/9748718.html

    装饰器pytest.hookimpl(hookwrapper=True)
    上面提到一个装饰器@pytest.hookimpl(hookwrapper=True),它的作用和装饰器@pytest.mark.hookwrapper是一样的,当pytest调用钩子函数时,它首先执行钩子函数装饰器并传递与常规钩子函数相同的参数(个人理解是当用该装饰器@pytest.hookimpl(hookwrapper=True)装饰时,他会把其他常规钩子函数的参数都传递给当前被装饰的钩子函数)

    在钩子函数装饰器的yield处,Pytest将执行下一个钩子函数实现,并以Result对象的形式,封装结果或异常信息的实例的形式将其结果返回到yield处。因此,yield处通常本身不会抛出异常(除非存在错误)

    总结如下:
    @pytest.hookimpl(hookwrapper=True)装饰的钩子函数,有以下两个作用:
    (1)可以获取到测试用例不同执行阶段的结果(setup,call,teardown)
    (2)可以获取钩子方法的调用结果(yield返回一个result对象)和调用结果的测试报告(返回一个report对象)

    @pytest.hookimpl(hookwrapper=True, tryfirst=True)
    def pytest_runtest_makereport(item, call): #对于给定的测试用例(item)和调用步骤(call),返回一个测试报告对象(_pytest.runner.TestReport)
      """
      每个测试用例执行后,制作测试报告
      :param item:测试用例对象
      :param call:测试用例的测试步骤
       执行完常规钩子函数返回的report报告有个属性叫report.when
    先执行when=’setup’ 返回setup 的执行结果
    然后执行when=’call’ 返回call 的执行结果
    最后执行when=’teardown’返回teardown 的执行结果
      :return:
      """
      # 获取常规钩子方法的调用结果,返回一个result对象
      out = yield
      # # 获取调用结果的测试报告,返回一个report对象, report对象的属性包括when(steup, call, teardown三个值)、nodeid(测试用例的名字)、outcome(用例的执行结果,passed,failed)
      report = out.get_result()
      print(out)
      print(report)
      print(report.when)
      print(report.nodeid)
      print(report.outcome)



    运行结果:执行三次的原因是此钩子函数会在测试用例执行的不同阶段(setup, call, teardown)都会调用一次

     1 testcase/test_getRegionCountry/test_GetRegionCountry.py::test_getRightrequest <pluggy.callers._Result object at 0x0000000004B7D828>
     2 <TestReport 'testcase/test_getRegionCountry/test_GetRegionCountry.py::test_getRightrequest' when='setup' outcome='passed'>
     3 setup
     4 testcase/test_getRegionCountry/test_GetRegionCountry.py::test_getRightrequest
     5 passed
     6 <pluggy.callers._Result object at 0x0000000002FAA748>
     7 <TestReport 'testcase/test_getRegionCountry/test_GetRegionCountry.py::test_getRightrequest' when='call' outcome='passed'>
     8 call
     9 testcase/test_getRegionCountry/test_GetRegionCountry.py::test_getRightrequest
    10 passed
    11 PASSED<pluggy.callers._Result object at 0x000000000303F5F8>
    12 <TestReport 'testcase/test_getRegionCountry/test_GetRegionCountry.py::test_getRightrequest' when='teardown' outcome='passed'>
    13 teardown
    14 testcase/test_getRegionCountry/test_GetRegionCountry.py::test_getRightrequest
    15 passed



    参考链接
    pytest之插件pytest.hookimpl用法https://www.cnblogs.com/vevian/articles/12631555.html
    Hook 方法之 pytest_runtest_makereport:获取测试用例执行结果
    https://blog.csdn.net/waitan2018/article/details/104347519

    Hook函数排序/调用示例
    对于任何给定的钩子函数规格,可能存在多个实现,因此我们通常将钩子函数执行视为1:N的函数调用,其中N是已注册函数的数量。有一些方法可以影响钩子函数实现是在其他之前还是之后,即在N-sized函数列表中的位置:

    # Plugin 1
    @pytest.hookimpl(tryfirst=True)
    def pytest_collection_modifyitems(items):
    # will execute as early as possible
    ...
    
    # Plugin 2
    @pytest.hookimpl(trylast=True)
    def pytest_collection_modifyitems(items):
    # will execute as late as possible
    ...
    
    # Plugin 3
    @pytest.hookimpl(hookwrapper=True)
    def pytest_collection_modifyitems(items):
    # will execute even before the tryfirst one above!
    outcome = yield
    # will execute after all non-hookwrappers executed


    这是执行的顺序:

    Plugin3的pytest_collection_modifyitems被调用直到注入点,因为它是一个钩子函数装饰器。
    调用Plugin1的pytest_collection_modifyitems是因为它标有tryfirst=True。
    调用Plugin2的pytest_collection_modifyitems因为它被标记trylast=True(但即使没有这个标记,它也会在Plugin1之后出现)。
    插件3的pytest_collection_modifyitems然后在注入点之后执行代码。yield接收一个Result实例,该实例封装了调用非装饰器的结果。包装不得修改结果。
    以上使用tryfirst,trylast,以及结合hookwrapper=True的示例,它会影响彼此之间hookwrappers的排序

    参考链接
    Pytest权威教程19-编写钩子(Hooks)方法函数
    https://www.cnblogs.com/superhin/p/11478007.html

    pytest-html官方文档地址
    https://pypi.org/project/pytest-html/

    其余参考链接
    Pytest官方教程-20-编写钩子(hook)方法
    https://www.jianshu.com/p/b8178b693f87
    pytest进阶之html测试报告
    https://www.cnblogs.com/linuxchao/p/linuxchao-pytest-report.html
    pytest文档20-pytest-html报告优化(添加Description)
    https://www.cnblogs.com/yoyoketang/p/9748718.html
    ————————————————
    版权声明:本文为CSDN博主「神奇的洋子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/u011035397/article/details/109546814

  • 相关阅读:
    C++: string的大小写转换
    c++自由的转换string和number
    C# 中的数据库操作~存储过程篇Mysql SqlServer
    Google Protocol Buffer Basics: C++
    C#中的扩展方法(向已有类添加方法,但无需创建新的派生类型)
    多态以及虚析构函数的使用
    【Java基础】String 相关知识点总结
    【设计模式】抽象工厂模式
    【设计模式】工厂方法模式
    【设计模式】简单工厂
  • 原文地址:https://www.cnblogs.com/superbaby11/p/16085897.html
Copyright © 2020-2023  润新知