相对于传统的xUnit的setup/teardown函数,fixture有如下改进:
1)测试fixture有明确的名称,通过在函数/模块/类或者整个项目中激活来使用
2)测试fixture是模块化的实现,使用fixture名即可触发特定的fixture,fixture可以在其他fixture中 进行使用
3)测试fixture不仅可以进行简单的单元测试,也可以进行复杂的功能测试。可以根据配置和组件的 选项进行参数化定制测试,或者跨函数/类/模块或者整个测试过程进行测试。
本文将讲解fixture带不同参数效果
一、fixture-带scope参数
scope参数可控制fixture的作用范围**(session>module>class>function)**
(一)function-每个引用fixture的函数,在执行之前都执行一次fixture
以登陆为例,进行举例–
scope=默认就是function,下面例子中
import pytest
@pytest.fixture()
def username():
print("\n登陆的用户名")
yz ="叶子"
return yz
@pytest.fixture(scope="function")
def password():
print("\n获取密码")
yz_pwd = "666666"
return yz_pwd
def test_one(username):
print("test_one获取的用户名:"+username)
assert username == "叶子"
def test_two(password):
print("test_two获取的密码:"+password)
assert password == "88888888"
def test_three(username,password):
print("test_three获取的用户名:"+username)
print("\ntest_three获取的密码:"+password)
assert username == "一休"
assert password == "6666666"
运行结果:
由于username和password在fixture引用scope分别使用默认和scope= “function”,通过实例我们可以看出两个效果是一样的
通过实例我们也看出,作用到function,在每个方法都需要进行重新执行fixture对应的方法
(二)class-每个引用fixture的类,在执行之前都执行一次fixture
每次执行一个class之前,执行fixture的函数(无论一个类里面有几个function,都只执行一次)
下面的例子:是工作中我们常用的场景:
前提是:测试同学=为“叶子”,产品同学=“产品大人”
测试同学是需要参加需求评审,并输出用例的(TestQAcase类)
产品同学是需要编写PRD,同时需要参加测试同学的用例评审的(TestPMcase类)
import pytest
@pytest.fixture(scope= "class")
def username():
print("\n登陆的用户名")
yz ="叶子"
return yz
class TestPMcase():
def test_work0(self,username):
print(username+" 来出需求文档")
assert username == "产品大人"
def test_work1(self,username):
print(username+" 来参加需求评审")
assert username == "叶子"
class TestQAcase():
def test_work0(self, username):
print(username + " 输出用例")
assert username == "叶子"
def test_work1(self, username):
print(username + " 来参加用例评审")
assert username == "产品大人"
执行结果如下:
通过实例可以看出,作用到class,在每个类前后只一次执行fixture对应的方法
(三)module-在每个.py文件执行之前都执行一次fixture
前面(一)(二)代码结构更改如下:
执行完后的结果:
通过实例可以看出,scope=modul时,每个py文件只执行一次
(四)session-无论执行多少py文件,只执行一次fixture
将(三)的配置文件我们更改一下:
import pytest
@pytest.fixture(scope= "session")
def username():
print("\n登陆的用户名")
yz ="叶子"
return yz
@pytest.fixture(scope="module")
def password():
print("\n获取密码")
yz_pwd = "666666"
return yz_pwd
执行后的效果:
二、fixture-带params参数
(1)列表
通过fixture将oneList的返回数据,供测试用例使用,在testcase中断言获取值是否正确
参数化(支持:列表[],元组(),字典列表[{},{},{}],字典元组({},{},{})
(2)参数化一个字典列表
测试百度查询的接口:“https://www.baidu.com”
分别设计3个用例:python-pytest-fixture
import pytest
import requests
params_list = [
{
"case":"查询python",
"headers":{},
"querystring":{"wd":"python"},
"payload":{},
"expected":{"status_code":200}
},
{
"case": "查询pytest",
"headers": {},
"querystring": {"wd": "pytest"},
"payload": {},
"expected": {"status_code": 200}
}, {
"case":"查询fixture",
"headers":{},
"querystring":{"wd":"fixture"},
"payload":{},
"expected":{"status_code":501}
}
]
@pytest.fixture(params= params_list)
def class_params(request):
return request.param
def test_baidu_search(class_params):
url = "https://www.baidu.com"
r = requests.request("GET",url,data = class_params["payload"],headers= class_params["headers"],params = class_params["querystring"]["wd"])
assert r.status_code == class_params["expected"]["status_code"]
执行结果:
**return的时候是param(不带s哦)
三、fixture-带autouse参数 True/False,默认为False
四、fixture-带ids参数 当使用params参数化时,给每一个值设置一个变量名,意义不大。
五、fixture-带name:给被@pytest.fixture标记的方法取一个别名。当取了别名后,那么原来的名称就用不了了。