Pytest_fixture(9)
什么是fixture
fixture是pytest特有的功能,使用装饰器 @pytest.fixture 标记的函数在其他函数中能被当作参数传入并被调用。
fixture有明确的名字,在其他函数,模块,类或整个工程调用它时会被激活。
fixture是基于模块来执行的,每个fixture的名字就可以触发一个fixture的函数,它自身也可以调用其他的fixture。
fixture作用是为了提供一种可靠和可重复的手段去运行那些最基本的测试内容。比如在测试网站的功能时,每个测试用例都要登录和退出,利用fixture就可以只做一次,否则每个测试用例都要做这两步就显得很冗余。
fixture的参数
fixture的可用参数如下:
- scope:定义被fixture装饰方法的作用域。可用参数值如下:
- function(默认):作用域为每个函数或方法
- class:作用域为每个类。
- module:作用域为每个模块(每个py文件)。
- session:作用域为每次启动。
- autouse=True:自动执行被fixture装饰的方法。默认为False
- params:用于参数化,数据类型支持列表和元组。(比如:params=[“v1”, "v2", "v3"])
- ids:当使用params参数化时,将nodeid中的变量值替换为给定的值(很少使用)
- name:给被fixture标记的方法取别名。(很少使用,注:当取了别名后,原方法名就不可以用了)
scope参数完成前后置操作
function:作用于每个函数(与setup和teardown功能相似)
import pytest # function作用范围为每个函数或方法
@pytest.fixture(scope="function")
def my_fixture():
# yield之前为前置操作,yield之后为后置操作
print("\n前置操作")
yield
print("\n后置操作") class TestPractice1: # 因为没使用autouse参数,使用时需要传入方法名
def test_001(self, my_fixture):
print("执行用例001") def test_002(self):
print("执行用例002") class TestPractice2: def test_003(self, my_fixture):
print("执行用例003") def test_004(self):
print("执行用例004")
执行结果

class:作用于每个类(与setup_class和teardown_class功能相似)
import pytest # class作用范围为每个类
@pytest.fixture(scope="class")
def my_fixture():
# yield之前为前置操作,yield之后为后置操作
print("\n前置操作")
yield
print("\n后置操作") class TestPractice1: # 因为没使用autouse参数,使用时需要传入方法名
def test_001(self, my_fixture):
print("执行用例001") def test_002(self):
print("执行用例002") class TestPractice2: def test_003(self):
print("执行用例003") def test_004(self, my_fixture):
print("执行用例004")
执行结果

module:作用于每个模块
import pytest # module作用范围为每个模块
@pytest.fixture(scope="module")
def my_fixture():
# yield之前为前置操作,yield之后为后置操作
print("\n前置操作")
yield
print("\n后置操作") class TestPractice1: # 因为没使用autouse参数,使用时需要传入方法名
def test_001(self, my_fixture):
print("执行用例001") def test_002(self):
print("执行用例002") class TestPractice2: def test_003(self):
print("执行用例003") def test_004(self, my_fixture):
print("执行用例004")
执行结果

session:作用于每次启动

autouse参数值为True时,被fixture装饰的函数自动被调用
上面我们使用被fixture装饰的函数,都需要将其函数名称当作参数传入到要使用的方法中。需要注意,自动执行范围与scope的作用域相关。
import pytest @pytest.fixture(autouse=True)
def my_fixture():
# yield之前为前置操作,yield之后为后置操作
print("\n前置操作")
yield
print("\n后置操作") class TestPractice1: # 因为没使用autouse参数,使用时需要传入方法名
def test_001(self):
print("执行用例001") def test_002(self):
print("执行用例002") class TestPractice2: def test_003(self):
print("执行用例003") def test_004(self):
print("执行用例004")
执行结果

params用于参数化,数据类型支持列表和元组。
在上面的例子中,fixture返回值都是None,我们可以选择让fixture返回我们需要的东西。如果你的fixture需要配置一些数据,读个文件,或者连接一个数据库,那么你可以让fixture返回这些数据或资源。
实现步骤:
- 在fixture中使用params参数;
- 在被fixture装饰的函数中添加request,request是固定写法;
- 使用 yield 或 return 返回 request.param request.param是固定写法;
- 在要使用的方法中,添加被fixture装饰的函数名;
注意:参数化时,如果使用了autouse,每个方法都会执行一次参数化,所以autouse慎用。
import pytest @pytest.fixture(params=[1, 2, 3])
def my_fixture(request):
# yield之前为前置操作,yield之后为后置操作
print("\n前置操作")
yield request.param
print("\n后置操作") class TestPractice1: # 参数化
def test_001(self, my_fixture):
print("执行用例001")
print(f"获取参数化的值:{my_fixture}") def test_002(self):
print("执行用例002")
执行结果

如果没有前后置操作,只想做参数化操作,我们可以使用return返回 request.param
import pytest @pytest.fixture(params=[1, 2, 3])
def my_fixture(request):
return request.param class TestPractice1: # 参数化
def test_001(self, my_fixture):
print("执行用例001")
print(f"获取参数化的值:{my_fixture}") def test_002(self):
print("执行用例002")
执行结果

ids用于在参数化时,将nodeid中的变量值替换为给定的值
import pytest @pytest.fixture(params=[1, 2, 3], ids=["v1", "v2", "v3"])
def my_fixture(request):
# yield之前为前置操作,yield之后为后置操作
return request.param class TestPractice1: # 参数化
def test_001(self, my_fixture):
print("执行用例001")
print(f"获取参数化的值:{my_fixture}") def test_002(self):
print("执行用例002")
执行结果

name用于给被fixture标记的方法取别名
name用于给被fixture标记的方法取别名
import pytest @pytest.fixture(name="rename_fixture")
def my_fixture(request):
print("前置操作")
yield
print("后置操作") class TestPractice1: # 使用方法别名调用fixture
def test_001(self, rename_fixture):
print("执行用例001") def test_002(self):
print("执行用例002")
需要注意是,使用该参数后,原函数名就不可用了。

fixture可以互相调用
import pytest @pytest.fixture()
def fixture_1():
print("\nfixture1的前置")
yield
print("fixture1的后置") # 在fixture_2中调用fixture_1
@pytest.fixture()
def fixture_2(fixture_1):
print("fixture2的前置")
yield
print("\nfixture2的后置") class TestPractice1: # 调用fixture_2
def test_001(self, fixture_2):
print("执行用例001") def test_002(self):
print("执行用例002")
执行结果

一个用例可以调用多个fixture
import pytest @pytest.fixture()
def fixture_1():
print("fixture1的前置")
yield
print("\nfixture1的后置") @pytest.fixture()
def fixture_2():
print("\nfixture2的前置")
yield
print("fixture2的后置") class TestPractice1: # 调用多个fixture,执行顺序与调用顺序有关
def test_001(self, fixture_2, fixture_1):
print("执行用例001") def test_002(self):
print("执行用例002")
执行结果

conftest.py和@pytest.fixture结合使用设置全局可用
上面的演示,用例和fixture均是在同一个文件中,我们可以创建一个固定名称为conftest.py的文件,将其放在用例同级或上级以上目录,在这个文件中定义一个被fixture装饰的函数,这个函数可以在其下级任意目录,不需要import而直接使用。
这里有以下几点需要注意:
- 文件名称固定为conftest.py
- 在conftest.py定义的fixture函数不需要import就可以直接使用
- conftest.py影响的作用域为同级及其所有子目录
- conftest.py文件可以创建多个,当多个文件存在相同的fixture函数名是,最近的作用域函数功能生效



Pytest_fixture(9)的更多相关文章
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- ASP.NET Core 之 Identity 入门(一)
前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库,负责对用户的身份进行认证,总体来说的话,没有MVC 5 里面那么复杂,因为在MVC 5里面引入了OW ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- Online Judge(OJ)搭建(第一版)
搭建 OJ 需要的知识(重要性排序): Java SE(Basic Knowledge, String, FileWriter, JavaCompiler, URLClassLoader, Secur ...
- 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑
阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...
- 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成
阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...
- 【.net 深呼吸】细说CodeDom(5):类型成员
前文中,老周已经厚着脸皮介绍了类型的声明,类型里面包含的自然就是类型成员了,故,顺着这个思路,今天咱们就了解一下如何向类型添加成员. 咱们都知道,常见的类型成员,比如字段.属性.方法.事件.表示代码成 ...
- 【.net 深呼吸】细说CodeDom(4):类型定义
上一篇文章中说了命名空间,你猜猜接下来该说啥.是了,命名空间下面就是类型,知道了如何生成命名空间的定义代码,之后就该学会如何声明类型了. CLR的类型通常有这么几种:类.接口.结构.枚举.委托.是这么 ...
随机推荐
- maven项目install时忽略执行test
1.在项目所在文件夹根目录使用maven命令打包时: <!-- 不执行单元测试,也不编译测试类 --> mvn install -Dmaven.test.skip=true 或 <! ...
- 微信小程序第一步
微信小程序开发文档https://developers.weixin.qq.com/miniprogram/dev/#小程序简介
- DevOps和SRE的区别
目录 一.误区 二.DevOps 和 SRE 定义 三.两者产生背景和历史 四.两者的职能不同 五.工作内容不同 六.DevOps 和 SRE 关系 七.附录:技能点 DevOps SRE 一.误区 ...
- [BUUCTF]PWN——[Black Watch 入群题]PWN
[Black Watch 入群题]PWN--栈劫持 入群题密码在 /password.txt Ubuntu 16 2020年02月27日:此入群题已作废,请看新版入群题. 附件 解题步骤: 例行检查, ...
- python selenium表单定位
在Web应用中经常会遇到frame/iframe 表单嵌套页面的应用,WebDriver 只能在一个页面上对元素识别与定位,对于frame/iframe 表单内嵌页面上的元素无法直接定位.这时就需要通 ...
- CF1057B DDoS 题解
Content 有一个长度为 \(n\) 的数列 \(a_1,a_2,...,a_n\),求出满足 \(\sum\limits_{i=l}^r a_i>100\times(r-l+1)\) 的区 ...
- 如何把maven项目转为eclipse项目
如何把maven项目转为eclipse项目,按照如下操作便可. 在cmd窗口, 载cmd窗口进入到maven项目所在目录下,输入如下命令: mvn eclipse:eclipse 这样便可.
- LocalDate转换成Date
LocalDate nowLocalDate = LocalDate.now(); Date date = Date.from(nowLocalDate.atStartOfDay(ZoneOffset ...
- Vue父子组件通信(父级向子级传递数据、子级向父级传递数据、Vue父子组件存储到data数据的访问)
Vue父子组件通信(父级向子级传递数据.子级向父级传递数据.Vue父子组件存储到data数据的访问) 一.父级向子级传递数据[Prop]: ● Prop:子组件在自身标签上,使用自定义的属性来接收外界 ...
- 平衡二叉树(c++实现)续
!!版权声明:本文为博主原创文章,版权归原文作者和博客园共有,谢绝任何形式的 转载!! 作者:mohist --- 欢迎指正--- 题外话:上一篇关于平衡二叉树文章中,我都没说自己是怎么理解的.别人终 ...