pytest fixture及conftest详解一 (各个参数的使用说明)

您所在的位置:网站首页 fixture作用域 pytest fixture及conftest详解一 (各个参数的使用说明)

pytest fixture及conftest详解一 (各个参数的使用说明)

#pytest fixture及conftest详解一 (各个参数的使用说明)| 来源: 网络整理| 查看: 265

文章目录 一、setup和teardown二、setup_class、teardown_class三、使用@pytest.fixture()装饰器来实现部分用例的前后置1、写法2、scope传不同参数值的区别a、function 函数级别,既每个函数执行,前后置方法也都会被执行b、class 类级别,既 前后置方法只执行一次c、module:模块级别d、package/session:模块级别 3、参数化使用: params案例:对用户名和密码进行校验 4、ids参数的使用案例 5、name参数的使用案例 四、通过conftest.py和@pytest.fixture()结合使用来实现全局的前置应用1、应用场景:2、conftest.py的特点 五、conftest.py中的yield使用

一、setup和teardown

setup:在每条测试用例开始执行前执行 testdown:在每条测试用例执行结束后执行

import pytest class TestDemo: def setup(self): print('在测试用例开始执行前执行') def test_01_work(self): print('执行测试用例1') def test_02_work(self): print('执行测试用例2') def teardown(self): print('在测试用例开始执行后执行') if __name__ == '__main__': pytest.main(['-vs','./test_demo1.py'])

执行结果

test_demo1.py::TestDemo::test_01_work 在测试用例开始执行前执行 执行测试用例1 PASSED在测试用例开始执行后执行 test_demo1.py::TestDemo::test_02_work 在测试用例开始执行前执行 执行测试用例2 PASSED在测试用例开始执行后执行 ============================== 2 passed in 0.30s ============================== 二、setup_class、teardown_class

setup_class:在每个类执行前的初始化工作:比如:创建日志对象,创建数据库的连接,创建接口的请求对象 teardown_class:在每个类执行后的扫尾工作:比如:销毁日志对象,断开数据库连接

import pytest class TestDemo: def setup_class(self): print('\n在每个类执行前的初始化工作:比如:创建日志对象,创建数据库的连接,创建接口的请求对象') def setup(self): print('在测试用例开始执行前执行') def test_01_work(self): print('执行测试用例1') def test_02_work(self): print('执行测试用例2') def teardown(self): print('在测试用例执行结束后执行') def teardown_class(self): print('\n在每个类执行后的扫尾工作:比如:销毁日志对象,断开数据库连接') if __name__ == '__main__': pytest.main(['-s','./test_demo1.py'])

执行结果

test_demo1.py::TestDemo::test_01_work 在每个类执行前的初始化工作:比如:创建日志对象,创建数据库的连接,创建接口的请求对象 在测试用例开始执行前执行 执行测试用例1 PASSED在测试用例执行结束后执行 test_demo1.py::TestDemo::test_02_work 在测试用例开始执行前执行 执行测试用例2 PASSED在测试用例执行结束后执行 在每个类执行后的扫尾工作:比如:销毁日志对象,断开数据库连接 ============================== 2 passed in 0.18s ==============================

在这里插入图片描述

三、使用@pytest.fixture()装饰器来实现部分用例的前后置 1、写法

@pytest.fixture(scope=,params=,autouse=,ids=,name=) 参数说明: scope :表示的是被@pytest.fixture标记的方法的作用域。 【function:默认,class(类),module(模块),package/session】 params:参数化(支持:列表,元祖,字典列表[{},{},{}],字典元祖[(),(),()]) autouse:True:自动执行,默认False ids:当 使用params参数化时,给每一个值设置一个变量名,意义不大 name:给表示的是被pytest.fixture标记的方法取一个别名

2、scope传不同参数值的区别 a、function 函数级别,既每个函数执行,前后置方法也都会被执行

在这里插入图片描述 conftest.py文件

import pytest @pytest.fixture() def my_fixture(): print('这是前置方法') yield print('这是后置方法')

test_demo1.py文件 特别注意1:如果只让test_01_work 执行前后置,那么就只给这个方法设置my_fixture

import pytest class TestDemo: #如果只让test_01_work 执行前后置,那么就只给这个方法设置my_fixture def test_01_work(self,my_fixture): print('执行测试用例1') def test_02_work(self): print('执行测试用例2') if __name__ == '__main__': pytest.main(['-vsq','./test_demo1.py']) test_demo1.py 这是前置方法 执行测试用例1 .这是后置方法 执行测试用例2 . ============================== 2 passed in 0.21s ==============================

特别注意2:如果想让所有的方法 执行前后置,那么给所有的方法设置my_fixture

import pytest class TestDemo: #如果只让test_01_work 执行前后置,那么就只给这个方法设置my_fixture def test_01_work(self,my_fixture): print('执行测试用例1') def test_02_work(self,my_fixture): print('执行测试用例2') if __name__ == '__main__': pytest.main(['-vsq','./test_demo1.py'])

在这里插入图片描述

特别注意3:当用例很多的时候,每次都传这个参数,会很麻烦。fixture里面有个参数autouse,默认是False没开启的,可以设置为True开启自动使用fixture功能,这样用例就不用每次都去传参了,autouse设置为True,自动调用fixture功能。所有用例都会生效,包括类中的测试用例和类以外的测试用例。

import pytest @pytest.fixture(scope='function',autouse=True) def my_fixture(): print('这是前置方法') yield print('这是后置方法') import pytest class TestDemo: def test_01_work(self): print('执行测试用例1') def test_02_work(self): print('执行测试用例2') class TestDemo1: def test_03_work(self): print('执行测试用例3') def test_04_work(self): print('执行测试用例4') if __name__ == '__main__': pytest.main(['-vsq','./test_demo1.py']) 这是前置方法 执行测试用例1 .这是后置方法 这是前置方法 执行测试用例2 .这是后置方法 这是前置方法 执行测试用例3 .这是后置方法 这是前置方法 执行测试用例4 .这是后置方法 b、class 类级别,既 前后置方法只执行一次

autouse:True:自动执行,默认False conftest.py

import pytest @pytest.fixture(scope='class',autouse=True) def my_fixture(): print('这是前置方法') yield print('这是后置方法')

test_demo1.py文件

import pytest class TestDemo: def test_01_work(self): print('执行测试用例1') def test_02_work(self): print('执行测试用例2') if __name__ == '__main__': pytest.main(['-vsq','./test_demo1.py']) test_demo1.py 这是前置方法 执行测试用例1 .执行测试用例2 .这是后置方法 ============================== 2 passed in 0.26s ============================== c、module:模块级别

conftest.py

import pytest @pytest.fixture(scope='module',autouse=True) def my_fixture(): print('这是前置方法') yield print('这是后置方法')

test_demo1.py文件

import pytest class TestDemo: def test_01_work(self): print('执行测试用例1') def test_02_work(self): print('执行测试用例2') class TestDemo1: def test_03_work(self): print('执行测试用例3') def test_04_work(self): print('执行测试用例4') if __name__ == '__main__': pytest.main(['-vsq','./test_demo1.py']) test_demo1.py::TestDemo::test_01_work 这是前置方法 执行测试用例1 PASSED test_demo1.py::TestDemo::test_02_work 执行测试用例2 PASSED test_demo1.py::TestDemo1::test_03_work 执行测试用例3 PASSED test_demo1.py::TestDemo1::test_04_work 执行测试用例4 PASSED这是后置方法 ======================================================== 4 passed in 0.16s ======================================================== d、package/session:模块级别

在这里插入图片描述 conftest.py

import pytest @pytest.fixture(scope='session',autouse=True) def my1_fixture(): print('----这是前置方法----') yield print('----这是后置方法----')

test_demo1.py

import pytest class TestDemo: def test_01_work(self): print('执行测试用例1') def test_02_work(self): print('执行测试用例2') class TestDemo1: def test_03_work(self): print('执行测试用例3') def test_04_work(self): print('执行测试用例4') if __name__ == '__main__': pytest.main(['-vsq','./test_demo1.py'])

test_run1.py

import pytest class TestRun: def test_01_run(self): print('执行测试用例5') if __name__ == '__main__': pytest.main(['-vs','./test_demo1.py']) products/test_demo1.py::TestDemo::test_01_work ----这是前置方法---- 执行测试用例1 PASSED products/test_demo1.py::TestDemo::test_02_work 执行测试用例2 PASSED products/test_demo1.py::TestDemo1::test_03_work 执行测试用例3 PASSED products/test_demo1.py::TestDemo1::test_04_work 执行测试用例4 PASSED users/test_run1.py::TestRun::test_01_run 执行测试用例5 PASSED----这是后置方法---- ======================================================== 5 passed in 0.17s ======================================================== 3、参数化使用: params

fixture的参数可以解决大量重复代码工作,比如数据库的连接、查询、关闭等.同样可以使用参数化来测试多条数据用例。

conftest.py

import pytest @pytest.fixture(scope='function',params=['data1','data2','data3']) def my_fixture(request): print('这是前置方法') yield request.param print('这是后置方法')

test_demo1.py 如果只让test_01_work执行前后置,那么就只给这个方法设置my_fixture

import pytest class TestDemo: def test_01_work(self,my_fixture): print('执行测试用例1,',my_fixture) def test_02_work(self): print('执行测试用例2') class TestDemo1: def test_03_work(self): print('执行测试用例3') def test_04_work(self): print('执行测试用例4') if __name__ == '__main__': pytest.main(['-vsq','./test_demo1.py'])

执行结果

collected 6 items test_demo1.py 这是前置方法 执行测试用例1, data1 .这是后置方法 这是前置方法 执行测试用例1, data2 asdata2 .这是后置方法 这是前置方法 执行测试用例1, data3 asdata3 .这是后置方法 执行测试用例2 .执行测试用例3 .执行测试用例4 . ============================== 6 passed in 0.10s ==============================

在这里插入图片描述

案例:对用户名和密码进行校验

conftest.py

import pytest data=[{'user':'kobe','pwd':666666}, {'user':'curry','pwd':666666}, {'user':'james','pwd':666666},] @pytest.fixture(scope='function',params=data) def my_fixture(request): print('这是前置方法') yield request.param print('这是后置方法')

test_demo1.py

import pytest class TestDemo: def test_01_work(self,my_fixture): print('执行测试用例1,',my_fixture) assert my_fixture['user']=='kobe' and my_fixture['pwd']==666666 def test_02_work(self): print('执行测试用例2') class TestDemo1: def test_03_work(self): print('执行测试用例3') def test_04_work(self): print('执行测试用例4') if __name__ == '__main__': pytest.main(['-vsq','./test_demo1.py'])

执行结果

test_demo1.py 这是前置方法 执行测试用例1, {'user': 'kobe', 'pwd': 666666} .这是后置方法 这是前置方法 执行测试用例1, {'user': 'curry', 'pwd': 666666} F这是后置方法 这是前置方法 执行测试用例1, {'user': 'james', 'pwd': 666666} F这是后置方法 执行测试用例2 .执行测试用例3 .执行测试用例4 .

在这里插入图片描述

4、ids参数的使用

ids也是要结合着params一起使用的。当有多个 param 时,针对每一个 param,可以指定一个id, 然后,这个 id 会变成测试用例名字的一部分。如果没有提供 id,则 id 将自动生成。

案例

conftest.py

import pytest data=[{'user':'kobe','pwd':666666}, {'user':'curry','pwd':666666}, {'user':'james','pwd':666666},] @pytest.fixture(scope='function',params=data,ids=['data1','data2','data3']) def my_fixture(request): print('这是前置方法') yield request.param print('这是后置方法')

test_demo1.py

import pytest class TestDemo: def test_01_work(self,my_fixture): print('执行测试用例1,',my_fixture) assert my_fixture['user']=='kobe' and my_fixture['pwd']==666666 def test_02_work(self): print('执行测试用例2') class TestDemo1: def test_03_work(self): print('执行测试用例3') def test_04_work(self): print('执行测试用例4') if __name__ == '__main__': pytest.main(['-vs','./test_demo1.py'])

执行结果

collecting ... collected 6 items test_demo1.py::TestDemo::test_01_work[data1] 这是前置方法 执行测试用例1, {'user': 'kobe', 'pwd': 666666} PASSED这是后置方法 test_demo1.py::TestDemo::test_01_work[data2] 这是前置方法 执行测试用例1, {'user': 'curry', 'pwd': 666666} FAILED这是后置方法 test_demo1.py::TestDemo::test_01_work[data3] 这是前置方法 执行测试用例1, {'user': 'james', 'pwd': 666666} FAILED这是后置方法 test_demo1.py::TestDemo::test_02_work 执行测试用例2 PASSED test_demo1.py::TestDemo1::test_03_work 执行测试用例3 PASSED test_demo1.py::TestDemo1::test_04_work 执行测试用例4 PASSED 5、name参数的使用

当使用了别名之后,原来的名称就使用不了了。

案例

conftest.py

import pytest data=[{'user':'kobe','pwd':666666}, {'user':'curry','pwd':666666}, {'user':'james','pwd':666666},] @pytest.fixture(scope='function',params=data,ids=['data1','data2','data3'],name='fix') def my_fixture(request): print('这是前置方法') yield request.param print('这是后置方法')

test_demo1.py

import pytest class TestDemo: def test_01_work(self,fix): print('执行测试用例1,',fix) assert fix['user']=='kobe' and fix['pwd']==666666 def test_02_work(self): print('执行测试用例2') class TestDemo1: def test_03_work(self): print('执行测试用例3') def test_04_work(self): print('执行测试用例4') if __name__ == '__main__': pytest.main(['-vs','./test_demo1.py'])

执行结果

test_demo1.py::TestDemo::test_01_work[data1] 这是前置方法 执行测试用例1, {'user': 'kobe', 'pwd': 666666} PASSED这是后置方法 test_demo1.py::TestDemo::test_01_work[data2] 这是前置方法 执行测试用例1, {'user': 'curry', 'pwd': 666666} FAILED这是后置方法 test_demo1.py::TestDemo::test_01_work[data3] 这是前置方法 执行测试用例1, {'user': 'james', 'pwd': 666666} FAILED这是后置方法 test_demo1.py::TestDemo::test_02_work 执行测试用例2 PASSED test_demo1.py::TestDemo1::test_03_work 执行测试用例3 PASSED test_demo1.py::TestDemo1::test_04_work 执行测试用例4 PASSED 四、通过conftest.py和@pytest.fixture()结合使用来实现全局的前置应用 1、应用场景:

比如:项目的全局登录,模块的全局处理

2、conftest.py的特点

①conftest.py文件是单独存放的一个夹具配置文件,名称是不能更改的。 ②可以在不同的py文件中使用同一个fixture函数 ③原则上conftest.py需要和运行的用例放到同一个目录下,并且不需要做任何的import导入操作。

特别注意3 每个模块设置单独的前后置,也可以使用外部公共的前后置。 在这里插入图片描述 test_demo1.py

import pytest class TestDemo: def test_01_work(self): print('执行测试用例1') def test_02_work(self): print('执行测试用例2') class TestDemo1: def test_03_work(self): print('执行测试用例3') def test_04_work(self): print('执行测试用例4') if __name__ == '__main__': pytest.main(['-vsq','./test_demo1.py'])

test_run1.py

import pytest class TestRun: def test_01_run(self): print('执行测试用例5') if __name__ == '__main__': pytest.main(['-vs','./test_demo1.py'])

全局conftest.py

import pytest @pytest.fixture(scope='session',autouse=True) def my1_fixture(): print('----这是前置方法----') yield print('----这是后置方法----')

局部products\conftest.py

import pytest @pytest.fixture(scope='module',autouse=True) def my_fixture(): print('这是前置方法') yield print('这是后置方法')

局部users\conftest

import pytest @pytest.fixture(scope='module',autouse=True) def my_fixture(): print('这是前置方法') yield print('这是后置方法')

执行结果

products/test_demo1.py::TestDemo::test_01_work ----这是前置方法---- 这是前置方法 执行测试用例1 PASSED products/test_demo1.py::TestDemo::test_02_work 执行测试用例2 PASSED products/test_demo1.py::TestDemo1::test_03_work 执行测试用例3 PASSED products/test_demo1.py::TestDemo1::test_04_work 执行测试用例4 PASSED这是后置方法 users/test_run1.py::TestRun::test_01_run 这是前置方法 执行测试用例5 PASSED这是后置方法 ----这是后置方法----

特别注意:当脚本中既有全局conftest,也有局部conftest时,先执行全局的,后执行局部的 在这里插入图片描述

五、conftest.py中的yield使用

return和yeild的区别: 都是表示返回值的意思,但是return的后面不能有代码,yeild很后面可以有代码

yield语句之前的就会在测试用例之前使用,yield之后的语句就会在测试用例执行完成之后再执行。

常见的应用场景:@pytest.fixture可以用在selenium中测试用例执行前后打开、关闭浏览器的操作; yield返回driver对象去操作浏览器; @pytest.fixture可以用在接口自动化测试中操作登录,yield返回token;

conftest.py

import pytest @pytest.fixture(scope='session',autouse=True) def login(): token=获取到的值 print('token的值:',token) yield token print('退出登录')

test_demo1.py

import pytest class TestDemo: def test_01_work(self): print('执行测试用例1') def test_02_work(self): print('执行测试用例2') class TestDemo1: def test_03_work(self): print('执行测试用例3') def test_04_work(self): print('执行测试用例4') if __name__ == '__main__': pytest.main(['-vsq','./test_demo1.py'])

test_run1.py

import pytest class TestRun: def test_01_run(self,login): print('执行测试用例5,获取到的token为:',login) if __name__ == '__main__': pytest.main(['-vs','./test_demo1.py'])

执行结果

products/test_demo1.py::TestDemo::test_01_work token的值: 66666666666666666 执行测试用例1 PASSED products/test_demo1.py::TestDemo::test_02_work 执行测试用例2 PASSED products/test_demo1.py::TestDemo1::test_03_work 执行测试用例3 PASSED products/test_demo1.py::TestDemo1::test_04_work 执行测试用例4 PASSED users/test_run1.py::TestRun::test_01_run 执行测试用例5,获取到的token为: 66666666666666666 PASSED退出登录 ======================================================== 5 passed in 0.13s ========================================================


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3