前言
fixture是在测试函数运行前后,由pytest执行的外壳函数。fixture中的代码可以定制,满足多变的测试需求,包括定义传入测试中的数据集、配置测试前系统的初始状态、为批量测试提供数据源等等。fixture是pytest的精髓所在,类似unittest中setup/teardown,但是比它们要强大、灵活很多,它的优势是可以跨文件共享。
一、Pytest fixture
1.pytest fixture几个关键特性
- 有独立的命名,并通过声明它们从测试函数、模块、类或整个项目中的使用来激活
- 按模块化的方式实现,每个fixture都可以互相调用
- fixture可以实现unittest不能实现的功能,比如unittest中的测试用例和测试用例之间是无法传递参数和数据的,但是fixture却可以解决这个问题
- fixture的范围从简单的单元扩展到复杂的功能测试,允许根据配置和组件选项对fixture和测试用例进行参数化
2.Pytest fixture定义
- 定义fixture跟定义普通函数差不多,唯一区别就是在函数上加个装饰器@pytest.fixture(),fixture命名不要用test_开头,跟用例区分开。用例才是test_开头的命名;
- fixture装饰器里的scope有四个级别的参数:function(不写默认这个)、class、module、session;
- fixture可以有返回值,如果没有return,默认会是None;用例调用fixture的返回值,就是直接把fixture的函数名称作为参数传入;
- fixture可以返回一个元组、列表或字典;
- 测试用例可传单个、多个fixture参数;
- fixture与fixture间可相互调用;
3.Pytest fixture用法
1)用法一:作为参数使用
fixture的名字直接作为测试用例的参数,用例调用fixture的返回值,直接将fixture的函数名称当做变量名称;如果用例需要用到多个fixture的返回数据,fixture也可以返回一个元祖,list或字典,然后从里面取出对应数据。
① 将fixture函数作为参数传递给测试用例
@pytest.fixture()
def login():
print("this is login fixture")
user = "chen"
pwd = 123456
return user, pwd
def test_login(login):
"""将fixture修饰的login函数作为参数传递给本用例"""
print(login)
assert login[0] == "chen"
assert login[1] == 123456
assert "chen" in str(login)
② 同一个用例中传入多个fixture函数
@pytest.fixture()
def user():
user = "cris"
return user
@pytest.fixture()
def pwd():
pwd = "123456"
return pwd
def test_trans_fixture(user, pwd):
"""同一条用例中传入多个fixture函数"""
print(user, pwd)
assert "cris" in str(user)
assert pwd == "123456"
③ fixture函数之间的相互传递
@pytest.fixture()
def user2():
user = "cris"
return user
@pytest.fixture()
def login_info(user2):
"""fixture与fixture函数之间的相互传递"""
pwd = "e10adc3949ba59abbe56e057f20f883e"
return user2, pwd
def test_assert_login_info(login_info):
print(login_info)
print(type(login_info))
assert login_info[0] == "cris"
assert login_info[1] == "e10adc3949ba59abbe56e057f20f883e"
2)用法二:提供灵活的类似setup和teardown功能
Pytest的fixture另一个强大的功能就是在函数执行前后增加操作,类似setup和teardown操作,但是比setup和teardown的操作更加灵活;具体使用方式是同样定义一个函数,然后用装饰器标记为fixture,然后在此函数中使用一个yield语句,yield语句之前的就会在测试用例之前使用,yield之后的语句就会在测试用例执行完成之后再执行。
@pytest.fixture()
def run_function():
print("run before function...")
yield
print("run after function...")
def test_run_1(run_function):
print("case 1")
def test_run_2():
print("case 2")
def test_run_3(run_function):
print("case 3")
运行结果如下:
常见的应用场景:@pytest.fixture可以用在selenium中测试用例执行前后打开、关闭浏览器的操作:
@pytest.fixture()
def fixture_driver():
driver = webdriver.Chrome()
yield driver
driver.quit()
def test_baidu(fixture_driver):
driver = fixture_driver