Pytest中fixture的作用范围(六)

      前面介绍了fixture的参数化,以及conftest.py的系列知识,本文章主要总结fixture的参数scope,通过它可以指定

fixture的作用范围。scope的参数主要应用于控制fixture执行配置和销魂逻辑的频率。在scope的参数中主要有四个值

可以选择,分别是function(函数级别),class(类级别).module(模块级别),session(会话级别),它的默认值是函数级

别。下面依据各个案例来说明该参数的实际应用。

       先来看函数级别,也就是说函数级别中,每个测试函数只需要执行一次,配置代码在测试用例运行前执行,销魂代码

是在测试用例运行之后执行。见案例代码:

#!/usr/bin/python3
#coding:utf-8


import  pytest

@pytest.fixture(scope='function')
def api():
    print('开始执行')
    yield
    print('结束执行')


def test_login_001(api):
    assert  1==1

 

该fixture仅仅是函数级别的应用,不会应用于其他的方面,见执行后的结果信息:

platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0
rootdir: /Applications/code/stack/study/xunit/scope, inifile:
plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0
collected 1 item                                                               

test_001.py 
        SETUP    F api
        test_001.py::test_login_001 (fixtures used: api).
        TEARDOWN F api

=========================== 1 passed in 0.03 seconds ===========================

 

    下来看类级别的,类级别的主要指的是每个测试类需要运行一次,无论测试类里面有多少个测试方法,都会被执行到并且共享

fixture,见案例代码:

#!/usr/bin/python3
#coding:utf-8


import  pytest

@pytest.fixture(scope='class')
def api():
    print('开始执行')
    yield
    print('结束执行')



class TestLogin(object):
    def test_login_001(self,api):
        assert  1==1

    def test_login_002(self):
        assert  1==1

 

见执行后的结果信息:

========================================= test session starts ==========================================
platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0
rootdir: /Applications/code/stack/study/xunit/scope, inifile:
plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0
collected 2 items                                                                                      

test_001.py 
      SETUP    C api
        test_001.py::TestLogin::test_login_001 (fixtures used: api).
        test_001.py::TestLogin::test_login_002 (fixtures used: api).
      TEARDOWN C api

======================================= 2 passed in 0.04 seconds =======================================

 

      下来来看模块级别的,在模块级别的fixture每个模块只需要执行一次,无论模块里面有多少个测试函数,类方法,都可以共享

这个fixture,见案例代码:

import  pytest

@pytest.fixture(scope='module')
def api():
    print('开始执行')
    yield
    print('结束执行')

def test_login_001(api):
    assert  1==1


class TestApi(object):
    def test_api_001(self,api):
        assert  1==1

 

见执行后的结果信息:

========================================= test session starts =========================================
platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0
rootdir: /Applications/code/stack/study/xunit/scope, inifile:
plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0
collected 2 items                                                                                     

test_001.py 
    SETUP    M api
        test_001.py::test_login_001 (fixtures used: api).
        test_001.py::TestApi::test_api_001 (fixtures used: api).
    TEARDOWN M api

====================================== 2 passed in 0.03 seconds =======================================

 

    是否存在这样的一个疑问,函数级别的是否可以应用在类级别,类级别的是否可以应用额于函数级别了,见测试代码:

#!/usr/bin/python3
#coding:utf-8


import  pytest

@pytest.fixture(scope='function')
def api():
    print('开始执行')
    yield
    print('结束执行')

def test_login_001(api):
    assert  1==1


class TestApi(object):
    def test_api_001(self,api):
        assert  1==1

 

如上是函数级别的,可以看到,在类中也是应用了,执行后显示的是函数级别的,见输出:

=============================================== test session starts ===============================================
platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0
rootdir: /Applications/code/stack/study/xunit/scope, inifile:
plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0
collected 2 items                                                                                                 

test_001.py 
        SETUP    F api
        test_001.py::test_login_001 (fixtures used: api).
        TEARDOWN F api
        SETUP    F api
        test_001.py::TestApi::test_api_001 (fixtures used: api).
        TEARDOWN F api

============================================ 2 passed in 0.03 seconds =============================================

 

    最后一个是会话级别的,会话级别的fixture每次会话只需要运行一次,一次pytest会话中的所有测试函数,方法都可以共享该fixture,见

案例代码:

#!/usr/bin/python3
#coding:utf-8


import  pytest

@pytest.fixture(autouse=True,scope='session')
def wuya():
    print('start')
    yield
    print('end')

 

见测试代码的源码:

#!/usr/bin/python3
#coding:utf-8


import  pytest

def test_login_001():
    assert  1==1


class TestApi(object):
    def test_api_001(self):
        assert  1==1

 见执行后的输出信息:

================================== test session starts ===================================
platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0
rootdir: /Applications/code/stack/study/xunit/scope, inifile:
plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0
collected 2 items                                                                        

test_001.py 
SETUP    S wuya
        test_001.py::test_login_001 (fixtures used: wuya).
        test_001.py::TestApi::test_api_001 (fixtures used: wuya).
TEARDOWN S wuya

================================ 2 passed in 0.04 seconds ================================

    在pytest中也可以使用userfixture指定多个fixture,这样来标记测试函数或者测试的类,使用usefixture,需要在一个参数中

指定一个或者多个fixture字符串,这样的一个场景在特定的场景下还是可以的,见案例的测试代码:

#!/usr/bin/python3
#coding:utf-8


import  pytest

@pytest.fixture()
def api():
    return 1

@pytest.fixture()
def init():
    print('start')
    yield
    print('end')

@pytest.mark.usefixtures('api','init')
def test_login_001(api):
    assert  api==1

 

见执行后的结果信息:

=========================================== test session starts ===========================================
platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0
rootdir: /Applications/code/stack/study/xunit/scope, inifile:
plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0
collected 1 item                                                                                          

test_001.py 
        SETUP    F api
        SETUP    F init
        test_001.py::test_login_001 (fixtures used: api, init).
        TEARDOWN F init
        TEARDOWN F api

======================================== 1 passed in 0.02 seconds =========================================

 

在如上的结果信息中,就可以看到,测试函数共享了两个fixture。

      在前面使用fixture的时候说到了autouse的选项,也应该看到,如果不使用该选项,每次共享fixture都需要指定,但是使用了它后

就不需要指定了,那么标准的说法应该是:依据选项autouse=True,使作用域内的测试函数都执行该fixture,这与那些需要多次执行,

但不依赖任何的状态或者外部数据的代码配合的比较好。针对如上的代码修改,见修改后的源码:

#!/usr/bin/python3
#coding:utf-8


import  pytest

@pytest.fixture(autouse=True)
def api():
    return 1

@pytest.fixture(autouse=True)
def init():
    print('start')
    yield
    print('end')


def test_login_001(api):
    assert  api==1

 

见执行后输出的结果信息:

=================================== test session starts ====================================
platform darwin -- Python 3.7.4, pytest-4.0.2, py-1.8.0, pluggy-0.12.0
rootdir: /Applications/code/stack/study/xunit/scope, inifile:
plugins: html-1.22.0, allure-adaptor-1.7.10, metadata-1.8.0
collected 1 item                                                                           

test_001.py 
        SETUP    F api
        SETUP    F init
        test_001.py::test_login_001 (fixtures used: api, init).
        TEARDOWN F init
        TEARDOWN F api

================================= 1 passed in 0.01 seconds =================================

 

posted @ 2019-09-01 15:20  无涯(WuYa)  阅读(417)  评论(0)    收藏  举报