pytest 之 fixture
Fixture 源码详解:
fixture(scope='function',params=None,autouse=False,ids=None,name=None)
- scope: 作用域范围,有4个参数“function(默认),class,module,session”
-function:每一个函数或方法都会调用 -class:每一个类调用一次,一个类中可以有多个方法 -module:每一个.py文件调用一次,该文件内又有多个function和class -session:是多个文件调用一次,可以跨.py文件调用,每个.py文件就是module
- params: 一个可选的参数列表,实现参数化功能
@pytest.fixture(params=["harry","赫敏"],ids=["11",'22']) def login(request): # request是一个关键字,也是一个fixture print("login") return request.param #request.param固定写法 def test_search(login): print(login) print("搜索")
- autouse:默认 False,需要调用来激活fixture;如果为True,则所有用例自动调用fixture
- ids:用例标识ID,每个ids 对应于params,如果没有id 它们将从params自动生产
- name:fixture的重命名。如果使用了name,那只能将name传如,函数名不再生效,如:
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参数后,仍传入函数名称,会失败")
Fixture 用法
功能:Fixture 是为了测试用例的执行,初始化一些数据和方法,类似 setUp、tearDown 功能,但比setUp,tearDown 更灵活
1、调用fixture的三种方式:
- 直接传fixture函数名字调用
- 使用装饰器 @pytest.mark.usefixtures("test1")
区别:如果fixture有返回值,usefixture无法获取到返回值,这个是装饰器usefixture与用例直接传fixture参数的区别。
当fixture需要用到return出来的参数时,只能将参数名称直接当参数传入,不需要用到return出来的参数时,两种方式都可以。
- 使用 autouse =True 自动调用,如果要返回值,需要传 fixture函数名
作用域(scope)广泛:session>module>class>function
2、其他用法:
- 允许使用多个Fixture
- 可以提供测试数据,实现参数化的功能
- fixture 也可以调用 fixture
- 命令行:-setup-show 回溯fixture 的执行过程,查看当前文件调用的哪个fixture
样例:
@pytest.fixture(scope='module') # scope 设置作用域 def aa(): print("开始计算") token = datetime.datetime.now() return token @pytest.fixture() def bb(): print("再次计算") yield print("结束啦") # 调用方式一:直接通过函数名字调用,根据顺序调用 def test_order(aa): print("下单") print(aa) # 调用方式二:直接通过函数名字调用,调用顺序从内到外;这种调用方式不能调用返回值 @pytest.mark.usefixtures('aa') # @pytest.mark.usefixtures('bb') def test_order1(): print(aa) print("下单1")
conftest.py 用法
存在原因: fixture为session级别是可以跨.py模块调用的,也就是当我们有多个.py文件的用例的时候,如果多个用例只需调用一次fixture,那就可以设置为scope="session",并且写到conftest.py文件里。
- 数据共享的文件,文件名字固定的不能改,脚本运行优先运行该文件
- 可以存放fixture, hook函数
- 就近生效:当前 conftest.py 文件所在路径及其下级文件均可调用,优先调用当前包的conftest.py,其次上级包的conftest.py文件
- 当前目录一定要有__init__.py 文件,也就是在一个包下
- conftest.py⽂件绝对不能当⼀般的模块导入
@pytest.fixture(scope="module",autouse=True) def login(): print("登录操作") token = datetime.datetime.now() yield token # yield 相当于return 被调用时先执行yield前面的代码,最后执行yield之后的代码 print("登出操作") @pytest.fixture() def get_username(login): print(login) name='赫敏' print(name) return name
调用文件:
def test_cart(login): print(login) print("购物") def test_order(login): print(login) print("下单")