fixture和case数据传递

问题

使用fixture创建case的前后置的时候,会产生一个这样的疑问,fixture和case之间参数如何进行传递。举例:fixture前置进行登录,将用户名传递至case,case执行完用例后,将id传给后置。

fixture基础知识

import pytest


@pytest.fixture()
def fixture_1():
    print('---执行1号前置---')
    yield
    print('---执行1号后置---')


@pytest.fixture()
def fixture_2():
    print('---执行2号前置---')
    yield
    print('---执行2号后置---')


@pytest.fixture()
def fixture_3():
    print('---执行3号前置---')
    yield
    print('---执行3号后置---')


@pytest.fixture()
def fixture_4():
    print('---执行4号前置---')
    yield
    print('---执行4号后置---')


@pytest.fixture()
def fixture_5():
    print('---执行5号前置---')
    yield
    print('---执行5号后置---')


@pytest.fixture()
def fixture_6():
    print('---执行6号前置---')
    yield
    print('---执行6号后置---')


@pytest.fixture()
def fixture_7():
    print('---执行7号前置---')
    yield
    print('---执行7号后置---')


@pytest.fixture()
def fixture_8():
    print('---执行8号前置---')
    yield
    print('---执行8号后置---')


# 这里按照【从下到上的顺序】
@pytest.mark.usefixtures('fixture_5')
@pytest.mark.usefixtures('fixture_4')
@pytest.mark.usefixtures('fixture_3')
class TestDemo1:

    def test_case_1(self, fixture_1, fixture_2):
        print('---1号用例完成---')

    @pytest.mark.usefixtures('fixture_8')
    @pytest.mark.usefixtures('fixture_7')
    @pytest.mark.usefixtures('fixture_6')
    def test_case_2(self):
        print('---2号用例完成---')


if __name__ == "__main__":
    pytest.main(['-vs', 'test_demo1.py'])

这里有一个重要的知识点,使用fixture并不是只可以通过装饰器@pytest.mark.usefixtures实现,还可以通过case传入参的方式进行调用,虽然用例没有使用这些参数,但从执行的结果可知,fixture执行了。

test_demo1.py::TestDemo1::test_case_1 ---执行3号前置---
---执行4号前置---
---执行5号前置---
---执行1号前置---
---执行2号前置---
---1号用例完成---
PASSED---执行2号后置---
---执行1号后置---
---执行5号后置---
---执行4号后置---
---执行3号后置---

test_demo1.py::TestDemo1::test_case_2 ---执行6号前置---
---执行7号前置---
---执行8号前置---
---执行3号前置---
---执行4号前置---
---执行5号前置---
---2号用例完成---
PASSED---执行5号后置---
---执行4号后置---
---执行3号后置---
---执行8号后置---
---执行7号后置---
---执行6号后置---

解决我们fixture和case数据传递的问题,关键点就在于使用入参的方式给case传递fixture,不使用装饰器的方式。

解决方案代码

import pytest


@pytest.fixture
def make_customer_record():
    created_records = []

    def _make_customer_record(name):
        record = name
        created_records.append(record)
        return record
    # yield之前是前置,后面是后置
    yield _make_customer_record
    # 后置拿到用例存储过来的变量
    for record in created_records:
        print(record)


def test_customer_records(make_customer_record):
    # 通过调用的方式在case中指定位置执行指定的fixture前置,可以将需要传输的数据在前置中进行存储
    customer_1 = make_customer_record("Lisa")
    customer_2 = make_customer_record("Mike")
    customer_3 = make_customer_record("Meredith")
    print(customer_1, customer_2, customer_3)


if __name__ == "__main__":
    pytest.main(['-vs', 'test_demo5.py'])

特别注意

  • fixture中文翻译为固定装置,虽然我们一般使用fixture去构建前后置操作,但其实fixture并不仅仅只提供前后置方法构建的,它构建的方法可以在用例执行的任意位置进行执行。
  • 将fixture作为用例参数进行传输,即使case内部不主动调用,也会在指定的声明周期的位置进行执行。这里有一点对于强迫症的童鞋尤其需要注意的一点,pycharm会提示这些参数没有使用,你千万千万要知道,这里仅仅是配置,工厂会调用这些fixture函数的。当然如果你这样使用,一般也知道。
  • 装饰器执行顺序是由下往上,参数由左往右执行的。

扩展

import pytest


@pytest.fixture()
def fixture_1():
    print('---执行1号前置---')
    yield
    print('---执行1号后置---')


@pytest.fixture()
def fixture_2():
    print('---执行2号前置---')
    yield
    print('---执行2号后置---')


@pytest.fixture()
def fixture_3():
    print('---执行3号前置---')
    yield
    print('---执行3号后置---')


@pytest.fixture()
def fixture_4():
    print('---执行4号前置---')
    yield
    print('---执行4号后置---')


@pytest.fixture()
def fixture_5():
    print('---执行5号前置---')
    yield
    print('---执行5号后置---')


@pytest.fixture()
def fixture_6():
    print('---执行6号前置---')
    yield
    print('---执行6号后置---')


@pytest.fixture()
def fixture_7():
    print('---执行7号前置---')
    yield
    print('---执行7号后置---')


@pytest.fixture(scope="class")
def fixture_8():
    print('---执行8号前置---')
    yield
    print('---执行8号后置---')


# 这里按照【从下到上的顺序】
@pytest.mark.usefixtures('fixture_5')
@pytest.mark.usefixtures('fixture_4')
@pytest.mark.usefixtures('fixture_3')
class TestDemo1:

    def test_case_1(self, fixture_1, fixture_2, fixture_8):
        print('---1号用例完成---')

    @pytest.mark.usefixtures('fixture_8')
    @pytest.mark.usefixtures('fixture_7')
    @pytest.mark.usefixtures('fixture_6')
    def test_case_2(self):
        print('---2号用例完成---')

    @pytest.mark.usefixtures('fixture_8')
    def test_case_3(self):
        print('---3号用例完成---')


if __name__ == "__main__":
    pytest.main(['-vs', 'test_demo1.py'])

前面示例中并没有定义fixture的作用域,默认都是function,即所有case方法的前后置执行,上面这个代码在fixture8里将作用域变更为class,根据结果可知,无论通过什么方式调用fixture,他都会主动去识别作用域。可见pytest还是相当智能的。执行结果如下:

test_demo1.py::TestDemo1::test_case_1 ---执行8号前置---
---执行3号前置---
---执行4号前置---
---执行5号前置---
---执行1号前置---
---执行2号前置---
---1号用例完成---
PASSED---执行2号后置---
---执行1号后置---
---执行5号后置---
---执行4号后置---
---执行3号后置---

test_demo1.py::TestDemo1::test_case_2 ---执行6号前置---
---执行7号前置---
---执行3号前置---
---执行4号前置---
---执行5号前置---
---2号用例完成---
PASSED---执行5号后置---
---执行4号后置---
---执行3号后置---
---执行7号后置---
---执行6号后置---

test_demo1.py::TestDemo1::test_case_3 ---执行3号前置---
---执行4号前置---
---执行5号前置---
---3号用例完成---
PASSED---执行5号后置---
---执行4号后置---
---执行3号后置---
---执行8号后置---

你可能感兴趣的:(python,python)