前言
-
定义fixture跟定义普通函数差不多,唯一区别就是在函数上加个装饰器@pytest.fixture(),fixture命名不要用test_开头,跟用例区分开。用例才是test_开头的命名。
-
fixture是可以有返回值的,如果没return默认返回None。用例调用fixture的返回值,直接就是把fixture的函数名称当成变量传入
-
fixture装饰器里的scope有四个级别的参数。“function(不写默认这个)”,“class”,“module”or“session”
-
除scope之外。还有params、autouse、ids、name等。
-
fixture可以有返回值,如果没有return,默认会是None;用例调用fixture的返回值,就是直接把fixture的函数名称作为参数传入
-
fixture可以返回一个元组、列表或字典
-
test_用例可传单个、多个fixture参数
-
fixture与fixture间可相互调用
1、fixture可以返回一个元祖、列表、字典
代码示例:
import pytest
@pytest.fixture()
def postcode():
print("========打印装饰器函数=====")
user = 'admin'
pwd = '123'
return user, pwd
def test_01(postcode):
print(postcode)
assert postcode[0] == 'admin'
assert postcode[1] == '123'
if __name__ == '__main__':
pytest.main(['-sv', 'test_01.py'])
结果:
2、用例传多个fixture参数
代码示例:
import pytest
@pytest.fixture()
def user():
print("=======user装饰器函数===========")
user = 'root'
return user
@pytest.fixture()
def pwd():
print("========pwd装饰器函数=========")
pwd = '123456'
return pwd
def test_02(user, pwd):
print(user, pwd)
assert user == 'root'
assert pwd == '123456'
if __name__ == '__main__':
pytest.main(['-sv', 'test_02.py'])
结果:
3、fixture与fixture之间可以互相调用
import pytest
@pytest.fixture()
def first():
print("\n===first===")
user = 'root'
assert user == 'root'
return user
@pytest.fixture()
def second(first):
print("\n===second===")
pwd = 123456
assert pwd == 123456
return first, pwd
def test_01(second):
print('\n', second)
assert second[0] == 'root'
assert second[1] == 123456
if __name__ == '__main__':
pytest.main(['-sv', 'test_03.py'])
结果:
语法规则:
@pytest.fixture(scope=’’,params=’’,autouse=’’,ids=’’,name=’’)
scope:表示的是被@pytest.fixture标记的方法的作用域,function(默认),class,modte,package/session
在定义固件时,通过 scope 参数声明作用域,可选项有:
function: 函数级,每个测试函数都会执行一次固件;
class: 类级别,每个测试类执行一次,所有方法都可以使用;
module: 模块级,每个模块执行一次,模块内函数和方法都可使用;
session: 会话级,一次测试只执行一次,所有被找到的函数和方法都可用。
Params: 参数化
Autouse = true :自动执行,默认False
Ids :当使用params参数化时,给每一个值一个变量名,意义不大。
name: 表示的是被@pytest.fixture标记的方法取一个别名。
1、function级别,在函数前后执行
代码示例:
import pytest
@pytest.fixture(scope="function")
def login():
print("--这是前置方法--")
user = 'root'
pwd = '123'
yield user, pwd
print("--这是后置方法--")
class TestDemo:
def test01(self):
print("\ntest01")
def test02(self, login):
print("\ntest02")
assert login[0] == 'root'
assert login[1] == '123'
if __name__ == '__main__':
pytest.main(['-sv', 'test_05.py'])
结果:
小结:
yield和return,都可以返回值,并且返回的值可以在测试用例中获取。
yield生成器,返回一个对象(可以有多个值),yield后面可以接代码。
return返回一个值,return后面不能接代码。
如果加入autouse=True参数,那么表示自动使用,那么和setup,和teardown功能一致。
2、class级别,在类前后执行
若class中的每个test用例都调用了login,只在class所有用例执行前运行一次
代码示例:
import pytest
@pytest.fixture(scope="class")
def login():
print('\n---前置---')
a = 'root'
yield a
print('\n---后置---')
class TestCase1:
def test01(self, login):
print("\ntest01")
def test02(self, login):
print("\ntest02")
结果:
3、module级别,在模块前后执行
代码示例:
import pytest
@pytest.fixture(scope="module")
def login():
print("\n---前置---")
yield
print("\n---后置---")
class TestCase:
def test01(self, login):
print("\ntest01")
def test02(self, login):
print("\ntest02")
if __name__ == '__main__':
pytest.main(['-sv', 'test_07.py'])
结果: