pytest可以使用@pytest.fixture装饰器来装饰一个方法,被装饰的方法名可以作为一个参数传入到测试方法中。可以使用这种方法来完成测试之前的初始化,也可以返回数据给测试函数
1.将fixture作为函数参数
通常使用setup和teardown来进行资源的初始化。如果有这样的一个场景:测试用例1需要依赖登录,测试用例2不需要登录,测试3需要登录,这种场景setup,teardown无法实现,此时可以使用pytest fixture功能,在方法前面加上@pytest.fixture装饰器,加了这个装饰器的方法可以以参数的形式传入到方法里面执行。
例如在登录的时候,加上@pytest.fixture这个装饰器后,将这个用例方法名以参数的形式传到方法里,这个方法就会先执行这个登录方法,再去执行自身的用例步骤,如果没有传递到这个登录方法,就不会执行登录操作,直接执行已有的步骤
2.代码如下
import pytest
@pytest.fixture()
def login():
print("这是个登录方法")
return ("tom老师————223333")
@pytest.fixture()
def operate():
print("这是登录后的执行的方法")
def test_case1(login,operate):
print(login)
print("test_case1,需要登录")
def test_case2():
print("test_case2,不需要登录")
def test_case3(login):
print(login)
print("test_case3,需要登录")
执行后的结果:
从上面的结果可以看出,testcase1和test_case3运行之前执行了login方法,test_case2没有执行这个方法
3.执行范围内共享
fixture里面有一个参数scope,通过scope可以控制fixture的作用范围,根据作用范围大小划分:session>moudule>class>function,具体作用范围如下:
- function函数或者方法级别都会被调用
- class类级别调用一次
- module模块级别调用一次
- session是多个文件调用一次(可以跨.py文件调用,每个.py文件就是module)
例如整个模块有多条测试用例,需要在全部用例执行之前打开浏览器,全部执行完之后去关闭浏览器,打开和关闭操作只执行一次,如果每次都重新执行打开操作,会非常占用系统资源。这种场景除了setup_module,teardown_module可以实现,还可以通过设置模块级别的fixture装饰器(@pytest.fixture(scope="module"))来实现。
scope="module",module作用是整个模块都会生效。
4.代码如下:
import pytest
@pytest.fixture(scope="module")
def open():
print("打开浏览器")
yield
print("执行teardown!")
print("最后关闭浏览器")
@pytest.mark.usefixtures("open")
def test_search1():
print("test_search1")
raise NameError
pass
def test_search2(open):
print("test_search2")
pass
def test_search3(open):
print("test_search3")
pass
代码执行结果:
从上面运行结果可以看出,scope="module"与yield结合,相当于setup_module和teardown_module方法。整个模块运行之前调用了open()方法中的yield前面的打印输出“打开浏览器”,整个运行之后调用了yield后面的打印语句“执行teardown! ”与“关闭浏览器”。yield用来唤醒teardown的执行方法,如果用例出现异常,不影响yield后面的teardown执行。可以使用@pytest.mark.usefixutures装饰器来进行方法的传入。