zoukankan      html  css  js  c++  java
  • pytest---fixture运行规则

    1,fixture是依赖注入的一种形式

    2,fixture的发现先后规则为:测试类,测试模块,coftest,内置,第三方

      多个fixture的运行先后顺序:作用范围越高,越先运行,autouse的优先级高于非autouse的,有依赖的fixture先运行依赖的fixtue,按照注入的先后顺序执行 

    import pytest
    
    # fixtures documentation order example
    order = []
    
    
    @pytest.fixture(scope="session")
    def s1():
        order.append("s1")
    
    
    @pytest.fixture(scope="module")
    def m1():
        order.append("m1")
    
    
    @pytest.fixture
    def f1(f3):
        order.append("f1")
    
    
    @pytest.fixture
    def f3():
        order.append("f3")
    
    
    @pytest.fixture(autouse=True)
    def a1():
        order.append("a1")
    
    
    @pytest.fixture
    def f2():
        order.append("f2")
    
    
    def test_order(f1, m1, f2, s1):
        assert order == ["s1", "m1", "a1", "f3", "f1", "f2"]

    3,对于需要花费比较长时间的操作,放到fixture中并且使用scope参数添加范围,避免多次加载花费大量时间

    4, fixture的范围

      function,class,model,package,seesion

      可以动态来定义fixture的范围

    # 通过命令行的参数来控制fixture的范围
    def
    determine_scope(fixture_name, config): if config.getoption("--keep-containers", None): return "session" return "function" @pytest.fixture(scope=determine_scope) def docker_container(): yield spawn_containe

    5,fixture添加结束代码的方式

        1,通过yield关键字来做类似teardown的方法

        2,通过request.addfinalizer(方法名)的方式

    def test_end():
        logging.info('结束测试')
        
    @pytest.fixture(scope='session',autouse=True)
    def tear_down_py(request):
        a=2
        logging.info('开始')
        request.addfinalizer(test_end)  # 这里的参数为方法名
        return a
    

    6,测试用例中传递一些值到fixture中,然后fixture对这些数据进入处理后返回处理结果的方法

       使用request.node.get_closest_marker和@pytest.mark的方法来做

    @pytest.fixture
    def fixt(request):
        marker = request.node.get_closest_marker("fixt_data")
        if marker is None:
            # Handle missing marker in some way...
            data = None
        else:
            data = marker.args[0]
    
        # 对数据做处理
        data = data+1
        return data
    
    
    class TestLoginSuccess:
    
        @pytest.mark.fixt_data(42)
        def test_fixt(self, fixt):
            assert fixt == 42

    7,fixture也可以返回一个函数,在测试用例中多次调用这个fixture

      

    @pytest.fixture
    def get_name_func():
        # 用闭包的形式使fixture返回一个函数,然后在测试用例中可以多次调用
        def _get_name(name):
    
            return {'name':name, 'age': 12}
    
        return _get_name
    
    
    class TestLoginSuccess:
    
        def test_fixt(self, get_name_func):
            assert get_name_func('张三')['name'] == '张三'
            assert get_name_func('张四')['name'] == '张四'
            assert 0
    

      同样也可以使用yield关键字来对之前创造的一些数据进入teardown的处理

      

    @pytest.fixture
    def get_name_func():
        # 用闭包的形式使fixture返回一个函数,然后在测试用例中可以多次调用
    
        creat_list = []
    
        def _get_name(name):
            creat_list.append(name)
            logging.info(creat_list)
            return {'name':name, 'age': 12}
        
        yield _get_name
        # 对创建对数据进行处理
        creat_list=[]
        logging.info(creat_list)
    
    class TestLoginSuccess:
    
        def test_fixt(self, get_name_func):
            assert get_name_func('张三')['name'] == '张三'
            assert get_name_func('张四')['name'] == '张四'
            assert 0
    

      

    8, 参数化数据

      -k 运行id包含指定关键字的用例,  --collect-only:只展示所有要运行用例,不实际运行,并且展示出参数化数据的id

    @pytest.fixture(params=['123','456'],ids=['first','second'])
    def para_func(request):
        return request.param
    
    class TestLoginSuccess:
    
        def test_fixt(self, para_func):
            assert para_func == '123'

      对id进行动态生成

    def change_id(param):
        if '1' in param:
            return 'first'
        else:
            return 'second'
    
    
    @pytest.fixture(params=['123','456'],ids=change_id)
    def para_func(request):
        return request.param
    
    
    class TestLoginSuccess:
        def test_fixt(self, para_func):
            assert para_func == '123'
    

      对某个参数添加mark标记,在params中使用 pytest.param('789', marks=pytest.mark.skip),,

      注意这个和 pytest-html插件一起使用的时候会报一些内容错误,但依然可以使用

    @pytest.fixture(params=['123', '456', pytest.param('789', marks=pytest.mark.skip)])
    def para_func(request):
        return request.param
    
    
    class TestLoginSuccess:
        def test_fixt(self, para_func):
            assert para_func == '123'
    

      

    9,fixture之间可以互相使用,但是低作用范围的fixture不能调用高作用范围的fixture

    10,当参数化的fixture作用范围大于等于module时,pytest会自动按照参数进行分组,每一个参数只会初始化一次和结束一次,这样有可能会打乱正常的用例执行顺序

      这样是为了减少活动fixture的数量,

    @pytest.fixture(scope='module', params=['13', '456'])
    def para_func(request):
        print('开始')
        yield request.param
        print('结束')
    
    
    class TestLoginSuccess:
        def test_01(self, para_func):
            print('执行1')
            assert para_func == '123'
    
        def test_02(self, para_func):
            print('执行2')
    
            assert para_func == '123'

    ##############结果,首先会拿第一个参数进行初始化然后去该作用范围内去找是否有使用该参数的用例,有就执行该参数的用例,然后不结束,再在该范围内找下一个使用这个参数的用例,直到没有了,才执行结束。
              然后下一个参数进行初始化,再继续找。

    开始
    执行1
    F执行2
    F结束
    开始
    执行1
    F执行2
    F结束
    F

      

    11,使fixture在测试类,测试moduel,整个项目中生效,需要使用pytest.mark.usefixtures(“fixture名称”)的方式,注意:这个方法用在fixture上无用

    @pytest.fixture(scope='module', params=['13', '456'])
    def para_func(request):
        print('开始')
        yield request.param
        print('结束')
    
    pytestmark = pytest.mark.usefixtures("para_func")   # 使fixture在整个module中生效,必须使用pytestmark 变量接收
    
    # @pytest.mark.usefixtures("para_func")     # 使fixture在整个class中生效
    class TestLoginSuccess:
        def test_01(self):
            print('执行1')
            assert para_func == '123'
    
        def test_02(self):
            print('执行2')
            assert para_func == '123'

    ######写在ini文件中,使fixture在整个项目中都生效
    # content of pytest.ini
    [pytest]
    usefixtures = cleandir

      

    12,autouse参数谨慎使用,如果使用,尽量在配置/ini文件增加一个配置信息,来控制开启和关闭,避免资源的浪费

      

    13,fixture是可以被覆盖的,使用相同的名称,后面的fixture会覆盖前面的fixture,  

    6,后续  

          

  • 相关阅读:
    北京大学数学分析习题集参考解答03.07难题
    北京大学数学分析习题集参考解答03.06一致连续性
    北京大学数学分析习题集参考解答03.05最大、最小值
    北京大学数学分析习题集参考解答03.03中间值性质03.04初等函数的连续性
    北京大学数学分析习题集参考解答03.02连续函数的运算
    北京大学数学分析习题集参考解答03.01连续与间断
    [Oracle工程师手记] 利用 DBMS_SQLTUNE.report_sql_monitor 生成 SQL 语句的监控信息
    [Oracle工程师手记] Data Guard 环境中,查找最近发生的与 Data Guard 相关的错误的方法
    [Oracle 工程师手记] Windows 环境下,获取与 oracle 相关 registry 的小技巧
    [Oracle工程师手记]从RAC环境备份后向新环境(文件系统)恢复的试验
  • 原文地址:https://www.cnblogs.com/myy-py/p/13516684.html
Copyright © 2011-2022 走看看