【自动化测试】Pytest之Fixture参数详解及使用
Fixture参数详解及使用
Fixture的调用方式:
@pytest.fixture(scope="",params="",autouse="",ids="",name="") scope:标记的作用域。function(默认)、class、module、session params:参数化 autouse:True自动执行,默认是False ids:当使用params参数化时,给每一个值设置一个变量名,意义不大 name:给标记的方法取一个别名
scope作用范围
用于控制Fixture的作用范围
作用类似于Pytest的setup/teardown
默认取值为function(函数级别),控制范围的排序为:session > module > class > function
取值 | 范围 说明 |
---|---|
function | 函数级 每一个函数或方法都会调用 |
class | 函数级 模块级 每一个.py文件调用一次 |
module | 模块级 每一个.py文件调用一次 |
session | 会话级 每次会话只需要运行一次,会话内所有方法及类,模块都共享这个方法 |
作用范围function
@pytest.fixture() #或者 @pytest.fixture(scope='function')
# 场景一:做为参数传入 import pytest # fixture函数(类中) 作为多个参数传入 @pytest.fixture() def login(): print("打开浏览器") a = "account" return a @pytest.fixture() def logout(): print("关闭浏览器") class TestLogin: #传入lonin fixture def test_001(self, login): print("001传入了loging fixture") assert login == "account" #传入logout fixture def test_002(self, logout): print("002传入了logout fixture") def test_003(self, login, logout): print("003传入了两个fixture") def test_004(self): print("004未传入仍何fixture哦") if __name__ == '__main__': pytest.main()
运行结果:
从运行结果可以看出,fixture做为参数传入时,会在执行函数之前执行该fixture函数。再将值传入测试函数做为参数使用,这个场景多用于登录
# 场景二、Fixture的相互调用 import pytest # fixtrue作为参数,互相调用传入 @pytest.fixture() def account(): a = "account" print("第一层fixture") return a # Fixture的相互调用一定是要在测试类里调用这层fixture才会生次,普通函数单独调用是不生效的 @pytest.fixture() def login(account): print("第二层fixture") class TestLogin: def test_1(self, login): print("直接使用第二层fixture,返回值为{}".format(login)) def test_2(self, account): print("只调用account fixture,返回值为{}".format(account)) if __name__ == '__main__': pytest.main()
运行结果:
注:
- 即使fixture之间支持相互调用,但普通函数直接使用fixture是不支持的,一定是在测试函数内调用才会逐级调用生效
- 有多层fixture调用时,最先执行的是最后一层fixture,而不是先执行传入测试函数的fixture
- 上层fixture的值不会自动return,这里就类似函数相互调用一样的逻辑
作用范围class:
当测试类内的每一个测试方法都调用了fixture,fixture只在该class下所有测试用例执行前执行一次
测试类下面只有一些测试方法使用了fixture函数名,这样的话,fixture只在该class下第一个使用fixture函数的测试用例位置开始算,后面所有的测试用例执行前只执行一次。而该位置之前的测试用例就不管。
# 场景一 import pytest # fixture作用域 scope = 'class' @pytest.fixture(scope='class') def login(): print("scope为class") class TestLogin: def test_1(self, login): print("用例1") def test_2(self, login): print("用例2") def test_3(self, login): print("用例3") if __name__ == '__main__': pytest.main()
运行结果:
# 场景二 import pytest @pytest.fixture(scope='class') def login(): a = '123' print("输入账号密码登陆") class TestLogin: def test_1(self): print("用例1") def test_2(self, login): print("用例2") def test_3(self, login): print("用例3") def test_4(self): print("用例4") if __name__ == '__main__': pytest.main()
运行结果:
作用范围module
与class相同,只从.py文件开始引用fixture的位置生效
import pytest # fixture scope = 'module' @pytest.fixture(scope='module') def login(): print("fixture范围为module") def test_01(): print("用例01") def test_02(login): print("用例02") class TestLogin(): def test_1(self): print("用例1") def test_2(self): print("用例2") def test_3(self): print("用例3") if __name__ == '__main__': pytest.main()
运行结果:
作用范围session
session的作用范围是针对.py级别的,module是对当前.py生效,seesion是对多个.py文件生效
session只作用于一个.py文件时,作用相当于module
所以session多数与contest.py文件一起使用,做为全局Fixture(contest.py所在结构决定作用范围,也就是session的作用范围)
params参数
- Fixture的可选形参列表,支持列表传入
- 默认None,每个param的值,fixture都会去调用执行一次,类似for循环
- 可与参数ids一起使用,作为每个参数的标识
被Fixture装饰的函数要调用是采用:Request.param
ids参数化别名
用例标识ID
与params配合使用,一对一关系
例如,未配置ids之前,用例:
配置了IDS后:
autouse自动执行
默认False
若为True,刚每个测试函数都会自动调用该fixture,无需传入fixture函数名
由此我们可以总结出调用fixture的三种方式:
- 函数或类里面方法直接传fixture的函数参数名称
- 使用装饰器@pytest.mark.usefixtures()修饰
- autouse=True自动调用,无需传仍何参数,作用范围跟着scope走(谨慎使用)
示例:
name函数别名:
fixture的重命名
通常来说使用 fixture 的测试函数会将 fixture 的函数名作为参数传递,但是 pytest 也允许将fixture重命名
如果使用了name,那只能将name传如,函数名不再生效
调用方法:@pytest.mark.usefixtures("fixture1","fixture2")
import pytest @pytest.fixture(name="new_fixture") def test_name(): pass # 使用name参数后,传入重命名函数,执行成功 def test_1(new_fixture): print("使用name参数后,传入重命名函数,执行成功") # 使用name参数后,仍传入函数名称,会失败 def test_2(test_name): print("使用name参数后,仍传入函数名称,会失败")
运行结果:
常用方法
@pytest.fixtrue()
实现部分用例的前后置
@pytest.fixture(scope="function") def my_fixture(): print('\n前置方法,可以实现部分及全部用例的前置') yield print('\n后置方法,可以实现部分及全部用例的后置') class Test03: def test_01(self): print('测试1') def test_02(self, my_fixture): print('测试2') def test_03(self): print('测试3')
生成前后置处理结果:
@pytest.fixtrue()
scope、autouse和conftest.py结合使用
通过scope和autouse和conftest.py结合使用,可以任意控制任意文件中类或方法的前置和后置处理
import pytest @pytest.fixture(scope="class", autouse=True) def my_fixture(): print('\n前置方法,可以实现部分及全部用例的前置') yield print('\n后置方法,可以实现部分及全部用例的后置') class Test03: def test_01(self): print('测试1') def test_02(self, my_fixture): print('测试2') def test_03(self): print('测试3') if __name__ == '__main__': pytest.main()
@pytest.fixtrue()
用例参数化方法
利用fixture中params和request.param方法来实现参数化
import pytest @pytest.fixture(params=['成龙', '甄子丹']) # params可以是元组,也可以是列表 def my_fixture(request): print('\n前置') yield request.param print('\n后置') class Test03: def test_01(self, my_fixture): print("测试111" + my_fixture) def test_02(self): print("测试222") def test_03(self): print("测试333") if __name__ == '__main__': pytest.main()
进群交流、获取更多干货, 请关注微信公众号:

> > > 咨询交流、进群,请加微信,备注来意:sanshu1318 (←点击获取二维码)
> > > 学习路线+测试实用干货精选汇总:
https://www.cnblogs.com/upstudy/p/15859768.html
> > > 【自动化测试实战】python+requests+Pytest+Excel+Allure,测试都在学的热门技术:
https://www.cnblogs.com/upstudy/p/15921045.html
> > > 【热门测试技术,建议收藏备用】项目实战、简历、笔试题、面试题、职业规划:
https://www.cnblogs.com/upstudy/p/15901367.html
> > > 声明:如有侵权,请联系删除。
============================= 升职加薪 ==========================
更多干货,正在挤时间不断更新中,敬请关注+期待。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通