一、fixture与setup、teardown的作用差异。
1、一句话: setup、teardown能干的事情,fixture也能干,而且还能干的更得心应手。至于为啥,咱们细看:
。fixture 命名方式灵活,不局限于setup和teardown这几个命名;
。fixture 所在的配置文件conftest.py(这个文件名是固定的)配置里可以实现数据共享,不需要import就能自动找到一些配置;
。fixture 中的参数之一 scope="module"可以实现多个.py跨文件共享前置;
。fixyure 中的参数之一 scope="session"以实现多个.py跨文件使用一个session来完成多个用例;
。fixture 通过配置文件设置后,可以定制化的为各个用例服务,默认是 function 级别,每个用例都用到;
二、关于fixture中参数的解释。
fixture(scope="function", params=None, autouse=False, ids=None, name=None)-----这是源码中的内容
。scope="function: scope参数有四个级别参数:"function"(默认)、"class"、"module"、"session" ;
。params=None : 一个非必须的参数,它将导致多个参数调用fixture功能和所有测试使用它,默认为None;
。autouse=False :为True时,则为所有测试激活fixture func,为False(默认值),则显式需要参考来激活fixture;
。 ids=None : 每个字符串id的列表,每个字符串对应于params,这样他们就是测试ID的一部分,如果没有提供ID它们将从params自动生成;
。name=None :fixture的名称,这默认为装饰函数的名称。如果fixture在定义它的同一模块中使用,夹具的功能名称将被请求夹具的功能arg遮蔽;将装饰函数命名"fixture_<fixturename>",然后使用"@pytest.fixture(name='<fixturename>')"
三、fixture中主要参数传参场景
1、当 scope="function" 时:
。使用场景:用例1需要先登录,用例2不需要登录,用例3需要先登录
-------测试代码
import pytest
# 不带参数时默认scope="function"
@pytest.fixture()
def login():
print("输入账号,密码先登录")
def test_s1(login):
print('用例1:需要先登录,才能进行其他操作')
def test_s2(): # 不传login
print('用例2:不需要登录,就可以进行其他操作')
def test_s3(login):
print('用例3:需要先登录,才能进行其他操作')
if __name__ == "__main__":
pytest.main()
------- 测试结果
在 @pytest.fixture()中为空,即表示默认scope="function" ,后边在需要用到fixture的用例在执行前,都调用了它。
2、当 scope="module" 时:
。当scope="module"时,module作用是整个.py文件(模块)都会生效,用例调用时,参数写上函数名称就行
------- 测试代码:
import pytest
# scope="module" 时。
@pytest.fixture(scope="module")
def open():
print("打开被测系统首页")
def test_s1():
print("然后被执行用例1")
def test_s2(open):
print("然后被执行用例2")
def test_s3(open):
print("然后被执行用例3")
if __name__ == "__main__":
pytest.main()
-------测试结果:
在整个用例文件中,它只在第一个用例调用它之前执行了一次,后边的调用都没有执行。并且,只有在调用的时候才执行。
3、当 scope="session" 时:
(往下看)
4、fixture 作为公共文件,不同用例文件调用时:
当出现这个情况时,则 conftest.py 配置文件就要闪亮登场了。
使用场景:有一个万年不变的登录接口,有一个封装好的待测接口文件,还有一个封装好的用例文件(可能说法上不是很准确,先这样喊吧!!),以共享session为例说明。
用例场景:登录 ------修改银行卡信息-----查询商品列表------添加商品品牌
因为后边三个接口都是需要在登录后的环境下操作,所以就把登录的接口独立出来到fixture中去。
--------先明确关于conftest.py文件的一点--------
。 conftest.py 这个文件名称是固定的,不能改,改了就报错
。conftest.py 有且只有两种存在位置,一是和需要执行的用例在同一个package中,二是在需要执行的用例的父级目录中。
主目录结构:
conftest.py 文件内容:
import pytest
import requests
from test_B.B10_test_1 import login,update_bank,select_shangp,add_make
@pytest.fixture(scope="session")
def login_fixture():
print("必须要先输入密码登录后才可以执行的用例")
s = requests.session()
login(s)
return s
@pytest.fixture(scope="session")
def nologin_fixture():
print("不用登录的后就可以执行的用例")
s = requests.session()
return s
用例文件:
import requests
from test_B.B10_test_1 import login,update_bank,select_shangp,add_make
def test_get_info(login_fixture):
'''
所有的用例都是正常场景下的
:return:
'''
s = login_fixture
banking = update_bank(s,accountName="小虎子啊") # 修改
shangp = select_shangp(s) # 查询
assert banking["message"]=="操作成功。"
assert shangp["message"]=="操作成功。"
def test_get_info_1(login_fixture):
'''
部分用例是异常场景下的
:return:
'''
s = login_fixture
banking = update_bank(s,accountName="") # 修改
shangp = select_shangp(s) # 查询
assert banking["message"]=="开户名称不能为空
"
assert shangp["message"]=="操作成功。"
def test_get_make(login_fixture):
'''
所有的用例都是异常场景下的
:return:
'''
s = login_fixture
addmake = add_make(s,makename="九匹狼")
assert addmake["message"]=="品牌名称不能重复"
接口文件:
import requests
def login(s,userName="14687513290",password="123456"):
url = "http://1.17.11.3:180/webapi/login"
body = {
"userName":userName,
"password":password
}
r = s.post(url=url,json=body)
token = r.json()["data"]["token"]
header = {
"Content-Type": "application/json",
"Authorization": "%s"%token
}
s.headers.update(header)
def update_bank(s,accountName="小虎子"):
url = "http://1.17.11.3:180/webapi/user/updateBankinfo"
body = {
"bankName":"青海银行",
"bankAccount":"6228480020668298217",
"accountName":accountName,
"bankCode":"313851000018"
}
r = s.post(url=url,json=body)
return r.json()
def select_shangp(s):
url = "http://1.17.11.3:180/webapi/v1/product/list"
body = {
"pageIndex":0,
"pageSize":2,
"categoryId":-1,
"ctegoryParentId":-1,
"ownerId":"100208"
}
r = s.post(url=url,json=body)
return r.json()
def add_make(s,makename="八匹狼"):
url = "http://1.17.11.3:180/webapi/brand/add"
body = {"name":makename}
r = s.post(url=url,json=body)
return r.json()
if __name__ == '__main__':
s = requests.session()
login(s)
banking = update_bank(s,accountName="小虎子啊")
shangp = select_shangp(s)
add_make(s,makename="八匹狼")
执行结果:
可以看到,session实现了多个文件共享。而且通过conftest.py配置文件实现了登录操作的跨文件共享