一.前言1.前面一篇讲setup、teardown可以实现在执行用例前或结束后加入一些操作但这种都是针对整个脚本全局生效的2.场景用例1需要先登录用例2不需要登录用例3需要先登录。很显然无法用setup和teardown来实现2.1.fixture可以让我们自定义测试用例的前置条件二.fixture的优势1.命名方式灵活不局限于setup和teardown这几个命名1.1.conftest.py配置里可以实现数据共享不需要import就能自动找到fixture1.2.scopemodule可以实现多个.py跨文件共享前置1.3.scopesession以实现多个.py跨文件使用一个session来完成多个用例三.fixture参数列表pytest.fixture(scopefunction,paramsNone,autouseFalse,idsNone,nameNone)deftest():print(fixture初始化的参数列表)1.参数列表1.1.scope可以理解成fixture的作用域默认function还有class、module、package、session四个【常用】1.2.autouse默认False需要用例手动调用该fixture如果是True所有作用域内的测试用例都会自动调用该fixture1.3.name默认装饰器的名称同一模块的fixture相互调用建议写个不同的name1.4.session的作用域是整个测试会话即开始执行Pytest到结束测试四.测试用例如何调用fixture1.将fixture名称作为测试用例函数的输入参数2.测试用例加上装饰器pytest.mark.usefixtures(fixture_name)3.fixture设置autouseTrue# -*- coding: utf-8 -*-importpytest# 调用方式一pytest.fixturedeflogin():print(输入账号密码先登录)deftest_s1(login):print(用例 1登录之后其它动作 111)deftest_s2():# 不传 loginprint(用例 2不需要登录操作 222)# 调用方式二pytest.fixturedeflogin2():print(please输入账号密码先登录)pytest.mark.usefixtures(login2,login)deftest_s11():print(用例 11登录之后其它动作 111)# 调用方式三pytest.fixture(autouseTrue)deflogin3():print(auto)# 不是test开头加了装饰器也不会执行fixturepytest.mark.usefixtures(login2)defloginss():print(123)4.执行结果5.知识点5.1.在类声明上面加pytest.mark.usefixtures()代表这个类里面所有测试用例都会调用该fixture5.2.可以叠加多个pytest.mark.usefixtures()先执行的放底层后执行的放上层5.3.可以传多个fixture参数先执行的放前面后执行的放后面5.4.如果fixture有返回值用 pytest.mark.usefixtures()是无法获取到返回值的必须用传参的方式方式一五.fixture的实例化顺序1.较高scope范围的fixturesession在较低scope范围的fixture function 、class之前实例化【sessionpackagemoduleclassfunction】2.具有相同作用域的fixture遵循测试函数中声明的顺序并遵循fixture之间的依赖关系【在fixture_A里面依赖的fixture_B优先实例化然后到fixture_A实例化】3.自动使用autouseTrue的fixture将在显式使用传参或装饰器的fixture之前实例化# -*- coding: utf-8 -*-importpytest order[]pytest.fixture(scopesession)defs1():order.append(s1)pytest.fixture(scopemodule)defm1():order.append(m1)pytest.fixturedeff1(f3,a1):# 先实例化f3, 再实例化a1, 最后实例化f1order.append(f1)assertf3123pytest.fixturedeff3():order.append(f3)a123yieldapytest.fixturedefa1():order.append(a1)pytest.fixturedeff2():order.append(f2)deftest_order(f1,m1,f2,s1):# m1、s1在f1后但因为scope范围大所以会优先实例化assertorder[s1,m1,f3,a1,f1,f2]六.关于fixture的注意点1.添加pytest.fixture 如果fixture还想依赖其他fixture需要用函数传参的方式1.1.不能用 pytest.mark.usefixtures()的方式否则会不生效pytest.fixture(scopesession)defopen():print(打开浏览器)pytest.fixture# pytest.mark.usefixtures(open) 不可取不生效deflogin(open):# 方法级别前置操作setupprint(f输入账号密码先登录{open})2.前面讲的其实都是setup的操作那么现在就来讲下teardown是怎么实现的七.fixture之yield实现teardown1.用fixture实现teardown并不是一个独立的函数而是用yield关键字来开启teardown操作# -*- coding: utf-8 -*-importpytestpytest.fixture(scopesession)defopen():# 会话前置操作setupprint(打开浏览器)test测试变量是否返回yieldtest# 会话后置操作teardownprint(关闭浏览器)pytest.fixturedeflogin(open):# 方法级别前置操作setupprint(f输入账号密码先登录{open})name我是账号pwd我是密码age我是年龄# 返回变量yieldname,pwd,age# 方法级别后置操作teardownprint(登录成功)deftest_s1(login):print(用例1)# 返回的是一个元组print(login)# 分别赋值给不同变量name,pwd,ageloginprint(name,pwd,age)assert账号innameassert密码inpwdassert年龄inagedeftest_s2(login):print(用例2)print(login)2.yield注意事项2.1.如果yield前面的代码即setup部分已经抛出异常则不会执行yield后面的teardown内容2.2.如果测试用例抛出异常yield后面的teardown内容还是会正常执行八.yieldwith的结合pytest.fixture(scopemodule)defsmtp_connection():withsmtplib.SMTP(smtp.gmail.com,587,timeout5)assmtp_connection:yieldsmtp_connection# provide the fixture value1.该smtp_connection连接将测试完成执行后已经关闭因为smtp_connection对象自动关闭时with语句结束九.addfinalizer 终结函数pytest.fixture(scopemodule)deftest_addfinalizer(request):# 前置操作setupprint(再次打开浏览器)testtest_addfinalizerdeffin():# 后置操作teardownprint(再次关闭浏览器)request.addfinalizer(fin)# 返回前置操作的变量returntestdeftest_anthor(test_addfinalizer):print(最新用例,test_addfinalizer)1.注意事项1.1.如果request.addfinalizer()前面的代码即setup部分已经抛出异常1.1.1.则不会执行request.addfinalizer()的teardown内容(和yield相似应该是最近新版本改成一致了)1.2.可以声明多个终结函数并调用
第四种:Pytest(四)-fixture的详细使用
发布时间:2026/7/14 18:13:32
一.前言1.前面一篇讲setup、teardown可以实现在执行用例前或结束后加入一些操作但这种都是针对整个脚本全局生效的2.场景用例1需要先登录用例2不需要登录用例3需要先登录。很显然无法用setup和teardown来实现2.1.fixture可以让我们自定义测试用例的前置条件二.fixture的优势1.命名方式灵活不局限于setup和teardown这几个命名1.1.conftest.py配置里可以实现数据共享不需要import就能自动找到fixture1.2.scopemodule可以实现多个.py跨文件共享前置1.3.scopesession以实现多个.py跨文件使用一个session来完成多个用例三.fixture参数列表pytest.fixture(scopefunction,paramsNone,autouseFalse,idsNone,nameNone)deftest():print(fixture初始化的参数列表)1.参数列表1.1.scope可以理解成fixture的作用域默认function还有class、module、package、session四个【常用】1.2.autouse默认False需要用例手动调用该fixture如果是True所有作用域内的测试用例都会自动调用该fixture1.3.name默认装饰器的名称同一模块的fixture相互调用建议写个不同的name1.4.session的作用域是整个测试会话即开始执行Pytest到结束测试四.测试用例如何调用fixture1.将fixture名称作为测试用例函数的输入参数2.测试用例加上装饰器pytest.mark.usefixtures(fixture_name)3.fixture设置autouseTrue# -*- coding: utf-8 -*-importpytest# 调用方式一pytest.fixturedeflogin():print(输入账号密码先登录)deftest_s1(login):print(用例 1登录之后其它动作 111)deftest_s2():# 不传 loginprint(用例 2不需要登录操作 222)# 调用方式二pytest.fixturedeflogin2():print(please输入账号密码先登录)pytest.mark.usefixtures(login2,login)deftest_s11():print(用例 11登录之后其它动作 111)# 调用方式三pytest.fixture(autouseTrue)deflogin3():print(auto)# 不是test开头加了装饰器也不会执行fixturepytest.mark.usefixtures(login2)defloginss():print(123)4.执行结果5.知识点5.1.在类声明上面加pytest.mark.usefixtures()代表这个类里面所有测试用例都会调用该fixture5.2.可以叠加多个pytest.mark.usefixtures()先执行的放底层后执行的放上层5.3.可以传多个fixture参数先执行的放前面后执行的放后面5.4.如果fixture有返回值用 pytest.mark.usefixtures()是无法获取到返回值的必须用传参的方式方式一五.fixture的实例化顺序1.较高scope范围的fixturesession在较低scope范围的fixture function 、class之前实例化【sessionpackagemoduleclassfunction】2.具有相同作用域的fixture遵循测试函数中声明的顺序并遵循fixture之间的依赖关系【在fixture_A里面依赖的fixture_B优先实例化然后到fixture_A实例化】3.自动使用autouseTrue的fixture将在显式使用传参或装饰器的fixture之前实例化# -*- coding: utf-8 -*-importpytest order[]pytest.fixture(scopesession)defs1():order.append(s1)pytest.fixture(scopemodule)defm1():order.append(m1)pytest.fixturedeff1(f3,a1):# 先实例化f3, 再实例化a1, 最后实例化f1order.append(f1)assertf3123pytest.fixturedeff3():order.append(f3)a123yieldapytest.fixturedefa1():order.append(a1)pytest.fixturedeff2():order.append(f2)deftest_order(f1,m1,f2,s1):# m1、s1在f1后但因为scope范围大所以会优先实例化assertorder[s1,m1,f3,a1,f1,f2]六.关于fixture的注意点1.添加pytest.fixture 如果fixture还想依赖其他fixture需要用函数传参的方式1.1.不能用 pytest.mark.usefixtures()的方式否则会不生效pytest.fixture(scopesession)defopen():print(打开浏览器)pytest.fixture# pytest.mark.usefixtures(open) 不可取不生效deflogin(open):# 方法级别前置操作setupprint(f输入账号密码先登录{open})2.前面讲的其实都是setup的操作那么现在就来讲下teardown是怎么实现的七.fixture之yield实现teardown1.用fixture实现teardown并不是一个独立的函数而是用yield关键字来开启teardown操作# -*- coding: utf-8 -*-importpytestpytest.fixture(scopesession)defopen():# 会话前置操作setupprint(打开浏览器)test测试变量是否返回yieldtest# 会话后置操作teardownprint(关闭浏览器)pytest.fixturedeflogin(open):# 方法级别前置操作setupprint(f输入账号密码先登录{open})name我是账号pwd我是密码age我是年龄# 返回变量yieldname,pwd,age# 方法级别后置操作teardownprint(登录成功)deftest_s1(login):print(用例1)# 返回的是一个元组print(login)# 分别赋值给不同变量name,pwd,ageloginprint(name,pwd,age)assert账号innameassert密码inpwdassert年龄inagedeftest_s2(login):print(用例2)print(login)2.yield注意事项2.1.如果yield前面的代码即setup部分已经抛出异常则不会执行yield后面的teardown内容2.2.如果测试用例抛出异常yield后面的teardown内容还是会正常执行八.yieldwith的结合pytest.fixture(scopemodule)defsmtp_connection():withsmtplib.SMTP(smtp.gmail.com,587,timeout5)assmtp_connection:yieldsmtp_connection# provide the fixture value1.该smtp_connection连接将测试完成执行后已经关闭因为smtp_connection对象自动关闭时with语句结束九.addfinalizer 终结函数pytest.fixture(scopemodule)deftest_addfinalizer(request):# 前置操作setupprint(再次打开浏览器)testtest_addfinalizerdeffin():# 后置操作teardownprint(再次关闭浏览器)request.addfinalizer(fin)# 返回前置操作的变量returntestdeftest_anthor(test_addfinalizer):print(最新用例,test_addfinalizer)1.注意事项1.1.如果request.addfinalizer()前面的代码即setup部分已经抛出异常1.1.1.则不会执行request.addfinalizer()的teardown内容(和yield相似应该是最近新版本改成一致了)1.2.可以声明多个终结函数并调用