美文网首页pytest
Python Pytest自动化测试 获取测试用例执行结果

Python Pytest自动化测试 获取测试用例执行结果

作者: 白码会说 | 来源:发表于2020-11-27 22:34 被阅读0次

    Time will tell.

    Pytest 提供了很多钩子方法让我们对测试用例框架进行二次开发,可根据自己的需求进行改造。所以接下来就来学习下pytest_runtest_makereport这个钩子方法,更清晰地了解用例的执行过程,并获取每个用例的执行结果。

    pytest_runtest_makereport

    来看下相关源码:

    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是测试步骤,具体过程如下:

    1. 先执行 when=’setup’ 返回setup的执行结果。
    2. 然后执行 when=’call’ 返回call的执行结果。
    3. 最后执行 when=’teardown’ 返回teardown的执行结果。

    1、案例

    conftest.pypytest_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("123")
    
    

    运行结果:

    D:\soft\code\pytest_jenkins_demo\demo>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
    123
    ------------------------------------
    用例执行结果 <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 ===========================
    
    

    从结果可以看到,用例的过程会经历3个阶段:

    setup -> call -> teardown
    
    

    每个阶段会返回Result对象和TestReport对象,以及对象属性。setupteardown上面的用例默认没有,结果都是passed

    2、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执行结果的failed,后面的call用例和teardown都不会执行。

    此时用例的状态是error,也就是用例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("123")
        assert 1==0
    
    

    那么此时运行结果就是failed

    如果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("123")
    
    

    最终结果:1 passed, 1 error in 0.16 seconds 。

    3、只获取call结果

    我们在写用例时,如果保证setupteardown不报错,只关注用例的运行结果,前面的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 后置操作")
    
    

    以上就是全部内容了,如果你对自动化软件测试、面试题感兴趣可以加入我们扣裙一起学习175317069。会有各项测试学习资源发放,更有行业深潜多年的技术人分析讲解。

    最后愿你能成为一名优秀的测试工程师!

    欢迎【点赞】、【评论】、【关注】~

    Time will tell.(时间会说明一切)

    相关文章

      网友评论

        本文标题:Python Pytest自动化测试 获取测试用例执行结果

        本文链接:https://www.haomeiwen.com/subject/dnvfwktx.html