pytest之fixture用法

一、fixture是什么

fixture是pytest用于将测试前后进行预备、清理工作的代码处理机制。
相较于setup和teardown而言,有以下几点优势:

  1. fixture命名更加灵活,局限性较小
  2. conftest.py配置里面可以实现数据共享,不需要import就能自动找到一些配置

二、fixture的scope

  1. (scope=“function”) 每一个函数或方法都会调用,默认就是function
# 示例:1、先定义一个fixture。这个fixture的函数不需要test_开头命名
@pytest.fixture(scope='function')
def  t_func1():
    print('function级别的前置操作:func1')

# 2、在用例里调用这个fixture 
def test_one(t_func1):
    expect = 1
    actual = 1
    assert expect == actual

执行后,在用例调用前会执行fixture里的操作:
pytest之fixture用法_第1张图片

  1. (scope=“class”) 每一个类调用一次
# 示例:1、先定义一个fixture。这个fixture的函数不需要test_开头命名
@pytest.fixture(scope='class',autouse=True)
def t_func2():
    print('class级别的前置操作:func2')

# 2、在用例里调用这个fixture 
class TestClassFixture():
    def test_one(self):
        expect = 1
        actual = 1
        print('ok')
        assert expect == actual

    def test_two(self):
        expect = 1
        actual = 2
        assert expect == actual

虽然类中有2个方法,但fixture的scope是class,因此只执行一次。
pytest之fixture用法_第2张图片

  1. (scope=“module”) 每一个.py文件调用一次
# 示例:1、先定义一个fixture。scope为module
@pytest.fixture(scope='module',autouse=True)
def t_module():
    print('module级别的前置操作')

#2、py文件中定义一个class一个函数
class TestClassFixture():
    def test_one(self):
        expect = 1
        actual = 1
        print('ok')
        assert expect == actual

    def test_two(self):
        expect = 1
        actual = 2
        assert expect == actual

def test_three():
    expect = 1
    actual = 2
    assert expect != actual

可以看到,虽然.py文件下存在一个类和一个函数。但只执行了一次前置操作pytest之fixture用法_第3张图片 4. (scope=“session”) 是多个文件调用一次

#1、在conftest.py中定义fixture
@pytest.fixture(scope='session',autouse=True)
def t_session():
    print('session级的fixture')

#2、同一个文件夹,创建2个.py文件
#3、terminal中执行pytest命令

可以看到,test_fixture这个文件下,虽然有test_one和test_two两个py文件,但只执行了一次前置操作。
pytest之fixture用法_第4张图片

  1. fixture的作用范围(执行顺序):session>module>class>function
@pytest.fixture(scope="function")
def t_function():
    print("我是function fixture")

@pytest.fixture(scope="class")
def t_class():
    print("我是class fixture")

@pytest.fixture(scope="module")
def t_moudule():
    print("我是moudule fixture")

@pytest.fixture(scope="session")
def t_session():
    print("我是session fixture")

class TestOrder:
    def test_order(self,t_function,t_session,t_moudule,t_class):
        assert 1==1

虽然打乱了顺序,但是执行顺序依然是session>module>class>function
pytest之fixture用法_第5张图片

三、使用conftest管理fixture

  1. conftest.py为固定写法,不可修改名字。使用conftest.py文件方法无需导入
  2. 函数作用于当前文件夹及下属文件,conftest可以放在上层目录,但是要注释掉当前目录的方法,如果方法都一样的话

四、fixture返回数据,解决接口参数依赖

#1、conftest.py文件中定义fixture
@pytest.fixture(scope="function")
def get_params():
    params = {'key1': 'value1', 'key2': 'value2'}
    return params

#2、用例文件中,使用fixture得到参数
import pytest
import requests

def test_getparam(get_params):
    print("测试get请求")
    #第1种方法
    r=requests.get('https://httpbin.org/get',params=get_params)

    #第2种方法
    key1 = get_params['key1']
    key2 = get_params['key2']
    r=requests.get('https://httpbin.org/get',params={'key1':key1, 'key2':key2})
    print(r.status_code)
    assert r.status_code == 200
    res = r.json()
    assert res['url'] == 'https://httpbin.org/get?key1=value1&key2=value2'
    assert res['origin'] == '163.125.202.248'
    assert res['args']['key1'] == 'value1'
    assert res['args']['key2'] == 'value2'

五、yield做后置操作

#1、conftest文件定义fixture,yield关键字之后可以定义后置操作
@pytest.fixture(scope='function')
def t_func1():
    print('function级别的前置操作:func1')
    yield
    print('function级别的后置操作:func1')


# 2、用例文件
def test_three(t_func1):
    expect = 1
    actual = 2
    assert expect != actual
    print('ok')

pytest之fixture用法_第6张图片

#1、conftest文件定义fixture,yield也可以返回值,但pytest中不常用这个用法
@pytest.fixture(scope='function')
def t_func1():
    print('function级别的前置操作:func1')
    yield 'potizo'
    print('function级别的后置操作:func1')
    
# 2、用例文件
def test_three(t_func1):
    expect = 1
    actual = 2
    assert expect != actual
    print('ok')
    print(t_func1)

pytest之fixture用法_第7张图片

六、fixture的另一种调用方式:uesfixtures

@pytest.fixture(scope='function',autouse=True)
def get_params():
    params = {
    		'key':'value'
        }
    return params    
  1. fixture的调用方式有2种,usefixtures这种无法接受返回值。
  • 第一种,可以接收返回值:
    def test_func(get_params):
    xxx

  • 第二种,无法接收返回值:
    @pytest.mark.usefixtures(‘get_params’)
    def test_func():
    xxx

  1. usefixtures的执行顺序
#1、conftest文件中定义2个fixture
@pytest.fixture(scope='function')
def t_func1():
    print('function级别的前置操作:func1')
    yield 'potizo'
    print('function级别的后置操作:func1')

@pytest.fixture(scope='function')
def t_func1_new():
    print('function级别的前置操作:func1_new')
    yield 'potizo'
    print('function级别的后置操作:func1_new')

#2、用例文件中使用usefixtures方式调用这两个fixture
@pytest.mark.usefixtures("t_func1")
@pytest.mark.usefixtures("t_func1_new")
def test_usefixtures():
    print('ok')

执行顺序:靠近方法的那个fixture先调用
pytest之fixture用法_第8张图片
也可以在usefixtures中一次调用多个fixture,用,分割。

@pytest.mark.usefixtures("t_func1","t_func1_new")
def test_usefixtures():
    print('ok')```

执行顺序如下:
pytest之fixture用法_第9张图片

七、fixture的2个参数:ids和params

# 1、 定义fixture 
#request和params\ids是关键字,不能改
@pytest.fixture(params=["data1","data2"],ids=["case1","case2"])
def params_fixture(request):
    return request.param
#2、 测试方法调用这个fixture
def test_params(params_fixture):
    print(params_fixture)

实际工作中很少这样用
pytest之fixture用法_第10张图片

你可能感兴趣的:(pytest,pytest,python)