Pytest--fixture详解

fixture

  • fixture介绍
    1.命名方式灵活,不局限于setup和teardown这几个命名
    2.conftest.py配置里可以实现数据共享

  • fixture源码详解
    @pytest.fixture(scope="function", params=None, autouse=False, ids=None, name=None)
    参数说明:
    scope:标记方法的作用域(functipn,class,module,session上篇文章有介绍)
    params:一个可选的参数列表,它将导致多个参数调用fixture功能和所有测试使用它
    autouse:默认:False,需要用例手动调用该fixture;如果是True,所有作用域内的测试用例都会自动调用该fixture
    ids:每个字符串id的列表,每个字符串对应于params这样他们就是测试ID的一部分。如果没有提供ID它们将从params自动生成
    name:fixture的名称。这默认为装饰函数的名称。如果fixture在定义它的统一模块中使用,夹具的功能名称将被请求夹具的功能arg遮蔽,解决这个问题的一种方法时将装饰函数命令"fixture_"然后使用"@pytest.fixture(name=fixturename)"

  • fixture具体使用
    1.将fixture作为测试函数的输入参数

#conftest.py
import pytest
@pytest.fixture(scope='function', autouse=False)
def open_server():
    a = 1
    print('---开启服务---')
    return a

@pytest.fixture(scope='function', autouse=False)
def close_server():
    print('---关闭服务---')

#test_case.py
    def test_run(self, open_server):
        print('---开始执行用例---')
        assert open_server == 1

#结果
test_001_case.py::TestCase001::test_run demo
---开启服务---
PASSED                           [100%]---开始执行用例---

2.Demo

@pytest.fixture
def step_1():
    print("调用了fixture1-----------")


@pytest.fixture
def step_2():
    print("调用了fixture2----------")


# 调用方式一,以参数传递
def test_001(step_1):
    print("用例 1: 111")


def test_002():  # 不传 step
    print("用例 2: 222")


# 调用方式二 测试用例加上装饰器:
#注意!!!如果fixture有返回值,那么usefixture就无法获取到返回值,这个是装饰器usefixture与用例直接传fixture参数的区别。
@pytest.mark.usefixtures(fixture_name),调用多个fixture用,隔开
@pytest.mark.usefixtures("step_1", "step_2")
def test_0003():
    print("用例3: 333")


# 调用方式三 fixture设置autouse=True
@pytest.fixture(autouse=True)
def step_3():
    print("调用了fixture3====auto===")


# 不是test开头,加了装饰器也不会执行fixture
@pytest.mark.usefixtures("step_2")
def case():
    print(123)

#结果
调用了fixture3====auto===
调用了fixture1-----------
用例 1: 111

.调用了fixture3====auto===
用例 2: 222

.调用了fixture3====auto===
调用了fixture1----------
调用了fixture2-----------
用例3: 333

3.assert在fixture里,断言失败就是error

@pytest.fixture()
def user():
    print("获取用户名")
    name = "xoxo"
    assert name == "oxox"  # fixture失败就是error
    return name

4.fixuer的params参数,简单的数据驱动

import pytest


class TestCase03:
    param = [
        ('www.baidu', '200'),
        ('www.xinlang', '300'),
    ]

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

    def test_01(self, data):
        assert data != 2

    @pytest.mark.parametrize('url,state', param)
    def test_02(self, url, state):
        print(url, state)

#结果
test_01:会运行三次
test_003.py::TestCase03::test_01[1] 
test_003.py::TestCase03::test_01[2] 
test_003.py::TestCase03::test_01[3]
test_02:
test_02[www.baidu-200] PASSED
test_02[www.xinlang-300] PASSED   

5.fixture中yield使用

#yield关键字实现teardown
#!!!如果yield前面的代码,即setup部分已经抛出异常了,则不会执行yield后面的teardown内容
import pytest

@pytest.fixture
def step():
    print("----执行用例前的操作")
    yield "这里是fixture的返回值"
    print("----执行用例后的操作")

def test_001(step):
    print(step)

if __name__ == '__main__':
    pytest.main(["-s", "xx.py"])
#结果:
------执行用例前的操作
这里是fixture的返回值
------执行用例后的操作
posted @ 2021-09-07 11:27  老猎人-note  阅读(339)  评论(0)    收藏  举报