pytest执行的顺序【收集测试用例、运行fixture函数、运行测试用例】|| 用例异常机制

pytest执行的顺序【收集测试用例、运行fixture函数、运行测试用例】

1、首先,pytest测试用例在执行之前,首先先收集测试套件中所有的测试用例。【对于参数化的测试用例(即使用了parametrize装饰器的用例),其实在测试收集阶段已经自动准备好了这些用例

可以参考【pytest修改测试用例执行顺序(钩子函数:pytest_collection_modifyitems)】这篇博客

复制代码
import pytest
from tools.read_config import *


class TestLogin1:
    def test_1(self):
        print(ReadConfig().read_config('project_GHelper', 'token'))

    @pytest.mark.skip
    def test_2(self):
        print('用例执行2')


class TestLogin2:
    @pytest.mark.parametrize('data1, data2', [(1, 2), ('a', 'b')], ids=['第一个测试用例', '第二个测试用例'])
    def test_3(self, data1, data2):
        print(data1, data2)
复制代码

运行结果:

【注意】收集需要运行的测试用例时,用例参数化部分会提前运行,即需要收集所有的测试用例数量;然后才开始执行测试用例,即执行测试方法体里面的程序。

示例:不能在用例参数化的时候替换token,因为每次运行fixture函数是在测试用例收集之后,此时的参数化已经完成。(此时的token时fixture函数执行之前的旧的token)

2、运行测试用例之前,会先查看该测试函数中的参数,然后搜索与这些参数具有相同名称的fixture。一旦pytest找到这些对象,它就会运行这些fixture。

【衍生:fixture的执行顺序】:https://www.cnblogs.com/cuitang/p/14958839.html,https://www.cnblogs.com/pingguo-softwaretesting/p/14698711.html

3、开始执行测试用例

用例异常机制

1、测试用例收集完成后,在执行测试用例期间的时候如果setup前置函数发生异常,则会中断测试用例的执行(即不会执行任何测试用例)

代码:

复制代码
# conftest.py
import pytest @pytest.fixture(scope='session', autouse=True) def get_token(): raise Exception('用例执行时setup前置操作执行期间发生异常') # 在收集完测试用例后才会执行 def pytest_collection_modifyitems(items): print('\npytest 收集到的所有测试用例:\n', items) for item in items: item.name = item.name.encode("utf-8").decode("unicode_escape") item._nodeid = item.nodeid.encode("utf-8").decode("unicode_escape") print('---' * 10) print('用例名:', item.name) print('用例节点:', item.nodeid) # 打印出每条参数化后的测试用例路径以及每条测试用例的ids
复制代码
复制代码
# test_002.py

import pytest

class TestDemoB:

    def test_B_001(self):
        pass

    def test_B_002(self):
        pass

    def test_B_003(self):
        pass


if __name__ == '__main__':
    pytest.main(['-vs', __file__])
复制代码

运行结果:

2、测试用例收集完成后,在执行完测试用例后如果teardown后置函数发生异常,不会中断测试用例的执行(因为此时的测试用例已经执行完成)

代码1:

复制代码
# conftest.py
import pytest @pytest.fixture(scope='function', autouse=True) def get_token(): print('用例执行前setup前置操作执行期间没有发生异常') yield raise Exception('用例执行完成后teardown后置函数执行期间发生异常') # 在收集完测试用例后才会执行 def pytest_collection_modifyitems(items): print('\npytest 收集到的所有测试用例:\n', items) for item in items: item.name = item.name.encode("utf-8").decode("unicode_escape") item._nodeid = item.nodeid.encode("utf-8").decode("unicode_escape") print('---' * 10) print('用例名:', item.name) print('用例节点:', item.nodeid) # 打印出每条参数化后的测试用例路径以及每条测试用例的ids
复制代码
复制代码
# test_002.py

import pytest

class TestDemoB:

    def test_B_001(self):
        pass

    def test_B_002(self):
        pass

    def test_B_003(self):
        pass


if __name__ == '__main__':
    pytest.main(['-vs', __file__])
复制代码

运行结果:

 代码2:

复制代码
# conftest.py

import pytest


@pytest.fixture(scope='function', autouse=True)
def get_token():
    print('用例执行前setup前置操作执行期间没有发生异常')
    yield
    raise Exception('用例执行完成后teardown后置函数执行期间发生异常')


# 在收集完测试用例后才会执行
def pytest_collection_modifyitems(items):
    print('\npytest 收集到的所有测试用例:\n', items)

    for item in items:
        item.name = item.name.encode("utf-8").decode("unicode_escape")
        item._nodeid = item.nodeid.encode("utf-8").decode("unicode_escape")
        print('---' * 10)
        print('用例名:', item.name)
        print('用例节点:', item.nodeid)  # 打印出每条参数化后的测试用例路径以及每条测试用例的ids
复制代码
复制代码
# test_002.py

import pytest


class TestDemoB:

    def test_B_001(self):
        print(1*100)

    def test_B_002(self):
        print('*'*100)

    def test_B_003(self):
        print('&'*100)


if __name__ == '__main__':
    pytest.main(['-vs', __file__])
复制代码

运行结果:

3、测试用例收集完成后,在执行测试用例时setup前置函数和teardown后置函数都没有发生异常,用例正常执行,正常断言获取测试用例执行结果。

代码:

复制代码
# conftest.py

import pytest

@pytest.fixture(scope='function', autouse=True)
def get_token():
    print('用例执行前setup前置操作执行期间没有发生异常')
    yield
    print('用例执行完成后teardown后置函数执行期间没有发生异常')


# 在收集完测试用例后才会执行
def pytest_collection_modifyitems(items):
    print('\npytest 收集到的所有测试用例:\n', items)

    for item in items:
        item.name = item.name.encode("utf-8").decode("unicode_escape")
        item._nodeid = item.nodeid.encode("utf-8").decode("unicode_escape")
        print('---' * 10)
        print('用例名:', item.name)
        print('用例节点:', item.nodeid)  # 打印出每条参数化后的测试用例路径以及每条测试用例的ids
复制代码
复制代码
# test_002.py

import pytest

class TestDemoB:

    def test_B_001(self):
        assert False

    def test_B_002(self):
        print('*'*100)

    def test_B_003(self):
        print('&'*100)


if __name__ == '__main__':
    pytest.main(['-vs', __file__])
复制代码

运行结果:

 

posted @   习久性成  阅读(789)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示