Python自动化框架入门2-fixture装饰器

fixture

pytest中使用fixture装饰器来装饰一个方法,被装饰的方法可以作为一个参数传到测试方法中,用于完成测试执行前的初始化,也可以返回数据给测试函数。

用法1:fixture作为函数参数

 通常使用setup teardown来进行资源的初始化。如果有这样一个场景,测试用例1和测试用例3需要依赖登录功能,测试用例2不需要依赖登录功能。这种场景setup,teardown无法实现,可以使用装饰器,加了这个装饰器的方法可以以参数的pytest fixture功能,在方法前面加个 @pytest.fixture形式传入到方法里面执行。

例如在登录的方法,加上 @pytest.fixture这个装饰器后,将这个用例方法名以参数的形式传到方法里,这个方法就会先执行这个登录方法,再去执行自身的用例步骤,如果有传入这个登录方法,就不执行登录操作,直接执行已有的步骤。

例子

import pytest

@pytest.fixture
def login():
    print("这是一个登录方法")
		return('jack','22')

@pytest.fixture()
def operate():
    print("登录后的操作")

def test_1(login,operate):
    print(login)
    print("test1,需要登录")

def test_2():
    print("test2,不需要登录")

def test_3():
    print(login)
    print("test3,需要登录")

在上面的代码中,测试case test1和case test3 分别增加login方法名作为参数,pytest会发现并调用pytest.fixture标记的login 功能

执行结果

test_fixture.py::test_1 这是一个登录方法
登录后的操作
PASSED                                           [ 33%]('jack', '22')
test1,需要登录

test_fixture.py::test_2 PASSED                                           [ 66%]test2,不需要登录

test_fixture.py::test_3 这是一个登录方法
PASSED                                           [100%]('jack', '22')
test3,需要登录

test1 和test3 分别执行了login方法,test2 没有执行 这个方法

fixture使用的三种方式

  • 如上文fixture注解下的函数方法名 直接作为测试用例的参数, def test_1(login,operate)
  • 使用@pytest.mark.usefixtures('fixture')装饰器
  •  使用autouse参数  @pytest.fixture(autouse=True)

指定fixture的参数autouse=True这样每个测试用例会自动调用fixture(其实这里说的不是很准确,因为还涉及到fixture的作用范围,那么我们这里默认是函数级别的,后面会具体说fixture的作用范围)

fixture 作用域 scope


    上述的实例默认都是函数级别的,所以测试函数只要调用了fixture,那么在测试函数执行前都会先指定fixture。说到作用范围就不得不说fixture 的第二个参数scope参数。

scope参数可以是session, module,class,function; 默认为function

  • session 会话级别(通常这个级别会结合conftest.py文件使用,所以后面说到conftest.py文件的时候再说)
  • module 模块级别: 模块里所有的用例执行前执行一次module级别的fixture
  • class 类级别 :每个类执行前都会执行一次class级别的fixture
  • function :函数级别,每个测试用例执行前都会执行一次function级别的fixture
@pytest.fixture(scope='module', autouse=True)
def module_fixture():
    print('我是module fixture')
@pytest.fixture(scope='class')
def class_fixture():
    print('我是class fixture')
@pytest.fixture(scope='function', autouse=True)
def func_fixture():
    print('我是function fixture')

执行普通测试方法:

def test_1():
    print('\n 我是test1')

执行结果为: function 函数级别,每个测试方法前都会执行

我是function

执行class 级别的case

执行结果为: function与class 作用域的函数 module 函数 只执行了一次

fixture实现 teardown

例子

import pytest

@pytest.fixture(scope="module")
def open():
    print("打开浏览器")
    yield

    print("执行teardown")
    print("关闭浏览器")

@pytest.mark.usefixtures("open")
def test_search1():
    print("test_search")
    raise NameError
    pass

def test_search2(open):
    print("test_search2")
    pass

def test_search3(open):
    print("test_search3")
    pass

执行结果

从上面的执行结果可以看出,scope="module“与yield 结合 相当于step_module与teardown_module,通过yield 唤醒teardown 的执行,若用例出现一场,不影响后面的yield与后面的teardown执行

 

fixture 传递参数

测试过程若需要大量的测试数据,则可以使用fixture的参数化功能

@pytest.fixture(params=[1,2,3])
def data(request):
    return request.param


def test_not2(data):
    print(f"测试数据:{data}")
    assert data <4 

conftest.py 全局调用

  • 可以跨.py文件调用,有多个.py文件调用时,可让conftest.py只调用了一次fixture,或调用多次fixture
  • conftest.py与运行的用例要在同一个pakage下,并且有__init__.py文件
  • 不需要import导入 conftest.py,pytest用例会自动识别该文件,放到项目的根目录下就可以全局目录调用了,如果放到某个package下,那就在改package内有效,可有多个conftest.py
  • conftest.py配置脚本名称是固定的,不能改名称
  • conftest.py文件不能被其他文件导入
  • 所有同目录测试文件运行前都会执行conftest.py文件
@pytest.fixture(scope="session")
def login():
    # yield 前面相当于 setup
    print("这里实现登录操作")
    token = "j;fdkafjadfa"
    # yield 相当于return
    yield
    # yield 后面相当于teardown操作
    print("实现登出操作")
执行结果

 

posted @ 2022-02-19 18:16  成子吃橙子  阅读(401)  评论(0编辑  收藏  举报