• allure钩子函数 && selenium 截图的四种方式 && allure集成错误截图报告


    1.selenium 截图的四种方式

    1. save_sreenshoot     #  一般不用 坑多
    2. get_sreenshoot_as_file  # 保存网页截图
    3. get_sreenshoot_as_png   #获取二进制数据流
    4.get_sreenshoot_as_base64  # base64编码原始数据

    2.allure的钩子函数

    Hooks 函数获取用例执行结果(pytest_runtest_makereport)

    看一下ruuner的源码  pytest执行测试原理   setup  call  teardown

    _pytest.runner

    from _pytest import runner
    
    # 对应源码
    def pytest_runtest_makereport(item, call):
        """ return a :py:class:`_pytest.runner.TestReport` object
        for the given :py:class:`pytest.Item` and
        :py:class:`_pytest.runner.CallInfo`.
        """

    这里item是测试用例,call是测试步骤,具体执行过程如下:

    • 先执行when='setup' 返回setup 的执行结果
    • 然后执行when='call' 返回call 的执行结果
    • 最后执行when='teardown'返回teardown 的执行结果

    运行实例

    conftest.py 写 pytest_runtest_makereport 内容,打印运行过程和运行结果

    # conftest.py 
    import pytest
    
    
    @pytest.hookimpl(hookwrapper=True, tryfirst=True)
    def pytest_runtest_makereport(item, call):
        print('------------------------------------')
    
        # 获取钩子方法的调用结果
        out = yield
        print('用例执行结果', out)
    
        # 3. 从钩子方法的调用结果中获取测试报告
        report = out.get_result()
    
        print('测试报告:%s' % report)
        print('步骤:%s' % report.when)
        print('nodeid:%s' % report.nodeid)
        print('description:%s' % str(item.function.__doc__))
        print(('运行结果: %s' % report.outcome))

    test_a.py写一个简单的用例

    def test_a():
        '''用例描述:test_a'''
        print("上海-悠悠")

    运行结果如下

    D:softcodepytest_jenkins_demodemo>pytest -s
    ============================= test session starts =============================
    platform win32 -- Python 3.6.0, pytest-4.5.0, py-1.5.4, pluggy-0.13.1
    rootdir: D:demo
    plugins: html-1.19.0,
    collected 1 item
    
    test_a.py ------------------------------------
    用例执行结果 <pluggy.callers._Result object at 0x0000027C547332B0>
    测试报告:<TestReport 'test_a.py::test_a' when='setup' outcome='passed'>
    步骤:setup
    nodeid:test_a.py::test_a
    description:用例描述:test_a
    运行结果: passed
    上海-悠悠
    ------------------------------------
    用例执行结果 <pluggy.callers._Result object at 0x0000027C547332B0>
    测试报告:<TestReport 'test_a.py::test_a' when='call' outcome='passed'>
    步骤:call
    nodeid:test_a.py::test_a
    description:用例描述:test_a
    运行结果: passed
    .------------------------------------
    用例执行结果 <pluggy.callers._Result object at 0x0000027C54750A20>
    测试报告:<TestReport 'test_a.py::test_a' when='teardown' outcome='passed'>
    步骤:teardown
    nodeid:test_a.py::test_a
    description:用例描述:test_a
    运行结果: passed
    
    
    ========================== 1 passed in 0.06 seconds ===========================

    从运行结果可以看出,运行用例的过程会经历三个阶段:setup-call-teardown,每个阶段都会返回的 Result 对象和 TestReport 对象,以及对象属性。
    setup和teardown上面的用例默认都没有,结果都是passed

    setup和teardown

    给用例写个fixture增加用例的前置和后置操作,conftest.py内容如下

    import pytest
    
    
    @pytest.hookimpl(hookwrapper=True, tryfirst=True)
    def pytest_runtest_makereport(item, call):
        print('------------------------------------')
    
        # 获取钩子方法的调用结果
        out = yield
        print('用例执行结果', out)
    
        # 3. 从钩子方法的调用结果中获取测试报告
        report = out.get_result()
    
        print('测试报告:%s' % report)
        print('步骤:%s' % report.when)
        print('nodeid:%s' % report.nodeid)
        print('description:%s' % str(item.function.__doc__))
        print(('运行结果: %s' % report.outcome))
    
    @pytest.fixture(scope="session", autouse=True)
    def fix_a():
        print("setup 前置操作")
        yield 
        print("teardown 后置操作")

    运行结果如下

    setup失败情况

    当setup执行失败了,setup的执行结果的failed,后面的call用例和teardown都不会执行了

     此时用例的状态是:error, 也就是用例(call)都还没开始执行,就异常了

    call失败情况

    如果setup正常执行,但是测试用例call失败了

    @pytest.fixture(scope="session", autouse=True)
    def fix_a():
        print("setup 前置操作")
        yield
        print("teardown 后置操作")

    test_a.py用例

    def test_a():
        '''用例描述:test_a'''
        print("上海-悠悠")
        assert 1==0

     那么此时运行的结果就是failed

    teardown失败了

    如果setup正常执行,测试用例call正常执行,teardown失败了,这种情况

    @pytest.fixture(scope="session", autouse=True)
    def fix_a():
        print("setup 前置操作")
        yield
        print("teardown 后置操作")
        raise Exception("teardown 失败了")

    teat_a.py用例

    def test_a():
        '''用例描述:test_a'''
        print("上海-悠悠")

     最终统计的结果: 1 passed, 1 error in 0.16 seconds

    只获取call的结果

    我们在写用例的时候,如果保证setup和teardown不报错情况,只关注测试用例本身的运行结果,前面的 pytest_runtest_makereport 钩子方法执行了三次。
    可以加个判断:if report.when == "call"

    import pytest
    from _pytest import runner
    '''
    # 对应源码
    def pytest_runtest_makereport(item, call):
        """ return a :py:class:`_pytest.runner.TestReport` object
        for the given :py:class:`pytest.Item` and
        :py:class:`_pytest.runner.CallInfo`.
        """
    '''
    
    @pytest.hookimpl(hookwrapper=True, tryfirst=True)
    def pytest_runtest_makereport(item, call):
        print('------------------------------------')
    
        # 获取钩子方法的调用结果
        out = yield
        # print('用例执行结果', out)
    
        # 3. 从钩子方法的调用结果中获取测试报告
        report = out.get_result()
        if report.when == "call":
            print('测试报告:%s' % report)
            print('步骤:%s' % report.when)
            print('nodeid:%s' % report.nodeid)
            print('description:%s' % str(item.function.__doc__))
            print(('运行结果: %s' % report.outcome))
    
    @pytest.fixture(scope="session", autouse=True)
    def fix_a():
        print("setup 前置操作")
        yield
        print("teardown 后置操作")

    运行结果

    3.allure报告集成错误截图

    需要使用conftest.py文件,conftest.py需要存在在测试目录中,文件名不能变更,可以根据模块创建层级嵌套。

    具体参照pytest的官方文档

    @pytest.hookimpl(tryfirst=True, hookwrapper=True)
    def pytest_runtest_makereport(item, call):
        '''
        hook pytest失败
        :param item:
        :param call:
        :return:
        '''
        # execute all other hooks to obtain the report object
        outcome = yield
        rep = outcome.get_result()
        # we only look at actual failing test calls, not setup/teardown
        if rep.when == "call" and rep.failed:
            mode = "a" if os.path.exists("failures") else "w"
            with open("failures", mode) as f:
                # let's also access a fixture for the fun of it
                if "tmpdir" in item.fixturenames:
                    extra = " (%s)" % item.funcargs["tmpdir"]
                else:
                    extra = ""
                f.write(rep.nodeid + extra + "
    ")
            # pic_info = adb_screen_shot()
            with allure.step('添加失败截图...'):
                allure.attach(driver.get_screenshot_as_png(), "失败截图", allure.attachment_type.PNG)
     

    4.Pytest+Allure+Selenuim+异常截屏+Allure日志

    需要使用conftest.py文件,conftest.py需要存在在测试目录中,文件名不能变更,可以根据模块创建层级嵌套。具体参照pytest的官方文档

    https://blog.csdn.net/cc8945203/article/details/103765505?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

  • 相关阅读:
    技术分享会之——智能指针
    TeleMCU技术规格
    Golang-interface(一 基本使用)
    关于Mac虚拟机中安装的Windows系统键盘问题
    Android 高速开发系列 打造万能的ListView GridView 适配器
    [Erlang]怎样在Erlang中使用SSL
    Web最新力作有奖试读获奖名单发布
    每天复习Shell—ls
    Mininet系列实验(七):Mininet脚本实现控制交换机行为
    Mininet系列实验(七):Mininet脚本实现控制交换机行为
  • 原文地址:https://www.cnblogs.com/bigbox/p/13141150.html
Copyright © 2020-2023  润新知