一、fixture详解
1、fixture概念:
fixture是pytest用于将测试前后进行预备、清理工作的代码处理机制。
2、fixture相对于setup和teardown来说有以下几点优势:
(1)fixture命名更加灵活,局限性比较小
(2)conftest.py配置里面可以实现数据共享,不需要import就能自动找到一些配置
3、fixture夹具,@pytest.fixture
(scop=‘function’)每一个函数或方法都会调用
(scop=‘class’)每一个类调用一次
(scop=‘module’)每一个.py文件调用一次
(scop=‘session’)是多个文件调用一次,.py文件就是module
fixture的作用范围:session>module>class>function
(1)(scop=‘function’)每一个函数或方法都会调用
'''
@Author : 测试工程师Selina
@FileName : test_fixture.py
@Description:
'''
import pytest
@pytest.fixture()
def func():
print('我是前置步骤')
def test_rule1(func):
assert 1 == 1
def test_rule2(func):
assert 2 == 2
print('pytest -q001')
if __name__ == '__main__':
pytest.main(['s', 'test_fixture.py'])
====================== test session starts ==========================
collecting ... collected 2 items
test_fixture.py::test_rule1
我是前置步骤
PASSED [ 50%]
test_fixture.py::test_rule2
我是前置步骤
PASSED [100%]pytest -q001
====================== 2 passed in 0.01s ==========================
'''
@Author : 测试工程师Selina
@FileName : test_fixture.py
@Description:
'''
import pytest
## @pytest.fixture(scope='function', autouse=True)
@pytest.fixture(autouse=True)
def func():
print('我是前置步骤')
def test_rule1():
assert 1 == 1
def test_rule2():
assert 2 == 2
print('pytest -q001')
if __name__ == '__main__':
pytest.main(['s', 'test_fixture.py'])
====================== test session starts ==========================
collecting ... collected 2 items
test_fixture.py::test_rule1
我是前置步骤
PASSED [ 50%]
test_fixture.py::test_rule2
我是前置步骤
PASSED [100%]pytest -q001
====================== 2 passed in 0.01s ==========================
(2)(scop=‘class’)每个类调用一次
'''
@Author : 测试工程师Selina
@FileName : test_fixture.py
@Description:
'''
import pytest
## @pytest.fixture(scope='class', autouse=True)
@pytest.fixture(scope='class')
def func():
print('我是前置步骤')
class Testclassfixture:
def test_rule1(self, func):
assert 1 == 1
def test_rule2(self, func):
assert 2 == 2
print('pytest -q001')
if __name__ == '__main__':
pytest.main(['s', 'test_fixture.py'])
====================== test session starts =========================
collecting ... collected 2 items
test_fixture.py::Testclassfixture::test_rule1
我是前置步骤
PASSED [ 50%]
test_fixture.py::Testclassfixture::test_rule2
PASSED [100%]pytest -q001
======================== 2 passed in 0.01s ===========================
(3)(scop=‘module’)每一个.py文件调用一次(不管这个文件里有多少方法,只运行一次)
'''
@Author : 测试工程师Selina
@FileName : test_fixture.py
@Description:
'''
import pytest
@pytest.fixture(scope='module', autouse=True)
def func():
print('我是前置步骤')
class Testclassfixture:
def test_rule1(self):
assert 1 == 1
def test_rule2(self):
assert 2 == 2
print('pytest -q001')
class Testfixture:
def test_rule3(self):
assert 1 == 1
def test_rule4(self):
assert 2 == 2
print('pytest -q001')
if __name__ == '__main__':
pytest.main(['s', 'test_fixture.py'])
====================== test session starts ===========================
collecting ... collected 4 items
test_fixture.py::Testclassfixture::test_rule1
我是前置步骤
PASSED [ 25%]
test_fixture.py::Testclassfixture::test_rule2
PASSED [ 50%]pytest -q001
test_fixture.py::Testfixture::test_rule3
PASSED [ 75%]
test_fixture.py::Testfixture::test_rule4
PASSED [100%]pytest -q001
========================= 4 passed in 0.01s ================================
(4)(scop=‘session’)是多个文件调用一次,.py文件就是module
一般所有的前置步骤放在conftest.py的文件中
二、pytest使用conftest管理fixture
为了方便测试框架的使用,所有的fixture前置后置内容都会放在conftest.py的文件中
'''
@Author : 测试工程师Selina
@FileName : test_fixture.py
@Description:
'''
import pytest
def test_rule1(func):
assert 1 == 1
def test_rule2(func):
assert 2 == 2
print('pytest -q001')
if __name__ == '__main__':
pytest.main(['s', 'test_fixture.py'])
================= test session starts =========================
collecting ... collected 2 items
test_fixture.py::test_rule1
我是前置步骤,我需要先运行
PASSED [ 50%]
test_fixture.py::test_rule2
我是前置步骤,我需要先运行
PASSED [100%]
pytest -q001
======================== 2 passed in 0.01s ==========================
三、pytest使用fixture返回数据
(1)return返回值
@pytest.fixture(scope='function')
def func():
return params
'''
@Author : 测试工程师Selina
@FileName : test_fixture.py
@Description:
'''
import pytest
import requests
@pytest.fixture()
def get_DoctorDept():
params = {'workerId': '1037', 'hospitalCode': '1'}
return params
def test_DoctorDept(get_DoctorDept):
Id = get_DoctorDept['workerId']
hospitalCode = get_DoctorDept['hospitalCode']
print('测试医生就诊科室')
r=requests.get('http://ip地址:端口号/outPatient/reception/getDoctorDept',
params={'workerId':Id,'hospitalCode':hospitalCode})
print(r.status_code)
(2)参数可以放在conftest.py文件中:
'''
@Author : 测试工程师Selina
@FileName : conftest.py
@Description:
'''
import pytest
@pytest.fixture()
def get_DoctorDept():
params = {'workerId': '1037', 'hospitalCode': '1'}
return params
@pytest.fixture(scope='session')
def test_session():
print('我是session级别的fixture')
四、pytest使用yield做后置处理
'''
@Author : 测试工程师Selina
@FileName : conftest.py
@Description: yield可以传参,一般不建议这样使用
'''
import pytest
@pytest.fixture(scope='function')
def func():
print('我是前置步骤,我需要先运行')
yield 'Selina'
print('我是后置步骤,我最后运行')
'''
@Author : 测试工程师Selina
@FileName : test_fixture.py
@Description:
'''
import pytest
def test_rule1(func):
assert 1 == 1
def test_rule2(func):
assert 2 == 2
print('pytest -q001')
============================= test session starts ==============================
collecting ... collected 2 items
test_fixture.py::test_rule1
我是前置步骤,我需要先运行
PASSED [ 50%]
我是后置步骤,我最后运行
test_fixture.py::test_rule2
我是前置步骤,我需要先运行
PASSED [100%]pytest -q001
我是后置步骤,我最后运行
============================== 2 passed in 0.01s ===============================
五、pytest的fixture执行顺序
fixture的作用范围:session>module>class>function
'''
@Author : 测试工程师Selina
@FileName : test_fixture.py
@Description: pytest的fixture执行顺序
'''
import pytest
@pytest.fixture(scope='session')
def t_session():
print('我是session级别的fixture')
@pytest.fixture(scope='module')
def t_module():
print('我是module级别的fixture')
@pytest.fixture(scope='class')
def t_class():
print('我是class级别的fixture')
@pytest.fixture(scope='function')
def t_function():
print('我是function级别的fixture')
class TestOrder:
def test_order(self, t_session, t_module, t_function, t_class):
assert 1 == 1
======================= test session starts ==========================
collecting ... collected 1 item
test_fixture_order.py::TestOrder::test_order
我是session级别的fixture
我是module级别的fixture
我是class级别的fixture
我是function级别的fixture
PASSED [100%]
========================= 1 passed in 0.01s =========================
六、pytest的usefixtures方法
@pytest.fixture(scope='function')
def func():
xxx
第一种,可以接受返回值
def test_func(func):
xxx
第二种,无法接收返回值
@pytest.mark.usefixtures('func')
def test_func():
xxx
七、pytest的fixture中的params和ids
(params=[‘参数1’,‘参数2’], ids=[‘用例1’],[‘用例2’])
'''
@Author : 测试工程师Selina
@FileName : test_fixture_params.py
@Description:
'''
import pytest
'''ids就是测试用例的名字,params是测试用例传递的参数'''
@pytest.fixture(params=['数据1', '数据2'], ids=['case1', 'case2'])
def params_fixture(request):
return request.param
def test_params(params_fixture):
print(params_fixture)
if __name__ == '__main__':
pytest.main(['s', 'test_fixture_params.py'])
====================== test session starts ===========================
collecting ... collected 2 items
test_fixture_params.py::test_params[case1]
PASSED [ 50%]数据1
test_fixture_params.py::test_params[case2]
PASSED [100%]数据2
===================== 2 passed in 0.01s ==============================
Process finished with exit code 0