pytest学习总结3.1 - 固定装置 fixture 深入解读

pytest学习总结3.1 - 固定装置 fixture 深入解读,第1张

文章目录
  • 3.1 固定装置 - fixture
    • 3.1.1 一些内置的固定装置
    • 3.1.2 固定装置如何使用?
      • 1、来自conftest.py的固定装置
      • 2、来自第三方插件的固定装置
    • 3.1.3 固定装置的调用顺序
      • 1、首先执行更高范围的固定装置
      • 2、基于依赖关系执行相同顺序的夹具
      • 3、固定装置首先在其范围内执行

3.1 固定装置 - fixture 3.1.1 一些内置的固定装置
  • capfd 捕获为文本,输出到文件描述符1和2
  • capfdbinary 捕获为字节符,输出到文件描述符1和2。


  • caplog 控制日志记录和访问日志项。


  • capsys 捕获,作为文本,输出到sys.stdout和sys.stderr
  • capsysbinary 捕获为字节,输出到sys.stdout和sys.stderr。


  • cache 在最测试运行中存储和检索值。


  • doctest_namespace 提供一个注入到文档目录名称空间中的字典。


  • monkeypatch 临时修改类、函数、字典、 *** 作系统、环境和其他对象。


  • pytestconfig 访问配置值、插件管理器和插件钩子
  • record_property 向测试中添加额外的属性。


  • record_testsuite_property 向测试套件中添加额外的属性。


  • recwarn 记录测试功能发出的警告
  • request 提供有关执行测试功能的信息
  • testdir 提供一个临时测试目录,以帮助运行和测试测试插件。


  • tmp_path 提供一个路径。


    路径对象到一个临时目录,该目录对每个测试函数都是唯一的。


  • tmp_path_factory 创建具有会话作用域的临时目录,并返回路径库。


    路径对象。


  • tmpdir 为一个临时目录提供一个py.path.local对象,该目录对每个测试函数都是唯一的;被tmp_path取代。


  • tmpdir_factory 创建会话作用域的临时目录并返回py.path.local对象;取代了tmp_path_factory。


3.1.2 固定装置如何使用?

一个夹具也可以请求任何其他夹具,无论它是在哪里定义的,只要请求它们的测试可以看到所有涉及的固定装置。


从测试的角度来看,他们可以毫无问题地看到他们所依赖的每个固定装置

import pytest
@pytest.fixture
def order():
    return []
@pytest.fixture
def outer(order, inner):
    order.append("outer")
class TestOne:
    @pytest.fixture
    def inner(self, order):
        order.append("one")
    def test_order(self, order, outer):
        assert order == ["one", "outer"]
class TestTwo:
    @pytest.fixture
    def inner(self, order):
        order.append("two")
    def test_order(self, order, outer):
        assert order == ["two", "outer"]

1、来自conftest.py的固定装置
  • conftest.py 文件用作为整个目录提供固定装置的一种方式,跨多个文件共享固定装置
  • 在conftest.py 中定义的夹具,可以被该包中的任何测试使用,而无需导入它们(pytest 将自动发现它们),
  • 你可以有多个包含测试的嵌套目录/包,并且每个目录都可以有自己的 conftest.py
  • 这些目录成为它们自己的范围,其中在该目录的 conftest.py 文件中定义的夹具可用于整个范围,允许测试向上搜索(走出圆圈)寻找夹具,但永远不能向下搜索继续他们的搜索。


    所以tests/subpackage/test_subpackage.py::test_order 将能够找到在tests/subpackage/test_subpackage.py中定义的最里面的fixture,但是在tests/subpackage/test_subpackage.py中定义的那个tests/test_top.py 将不可用,

tests/
    __init__.py

    conftest.py
        # content of tests/conftest.py
        import pytest
        @pytest.fixture
        def order():
            return []
        @pytest.fixture
        def top(order, innermost):
            order.append("top")
            
    test_top.py
        # content of tests/test_top.py
        import pytest
        @pytest.fixture
        def innermost(order):
            order.append("innermost top")
        def test_order(order, top):
            assert order == ["innermost top", "top"]
            
    subpackage/
        __init__.py

        conftest.py
            # content of tests/subpackage/conftest.py
            import pytest
            @pytest.fixture
            def mid(order):
                order.append("mid subpackage")
        test_subpackage.py
            # content of tests/subpackage/test_subpackage.py
            import pytest
            @pytest.fixture
            def innermost(order, mid):
                order.append("innermost subpackage")
            def test_order(order, top):
                assert order == ["mid subpackage", "innermost subpackage", "top"]

2、来自第三方插件的固定装置

如果安装了plugin_a并提供了夹具a_fix,并且安装了plugin_b并提供了夹具b_fix,那么这就是测试中搜索夹具的结果:

tests/
    __init__.py

    conftest.py
        # content of tests/conftest.py
        import pytest
        @pytest.fixture
        def order():
            return []

    subpackage/
        __init__.py

        conftest.py
            # content of tests/subpackage/conftest.py
            import pytest
            @pytest.fixture(autouse=True)
            def mid(order, b_fix):
                order.append("mid subpackage")

        test_subpackage.py
            # content of tests/subpackage/test_subpackage.py
            import pytest
            @pytest.fixture
            def inner(order, mid, a_fix):
                order.append("inner subpackage")
            def test_order(order, inner):
                assert order == ["b_fix", "mid subpackage", "a_fix", "inner subpackage˓→"]

3.1.3 固定装置的调用顺序

当 pytest 想要执行测试时,一旦它知道要执行哪些夹具,它就必须弄清楚它们的执行顺序,它考虑了 3 个因素:

  • scope
  • dependencies
  • autouse
1、首先执行更高范围的固定装置

fixture执行的时候,较高范围(session)的固定装置在较低范围的固定装置之前(class、方法)执行:

import pytest
@pytest.fixture(scope="session")
def order():
    return []

@pytest.fixture
def func(order):
    order.append("function")
@pytest.fixture(scope="class")
def cls(order):
    order.append("class")
@pytest.fixture(scope="module")
def mod(order):
    order.append("module")
@pytest.fixture(scope="package")
def pack(order):
    order.append("package")
@pytest.fixture(scope="session")
def sess(order):
    order.append("session")
class TestClass:
    def test_order(self, func, cls, mod, pack, sess, order):
        assert order == ["session", "package", "module", "class", "function"]

2、基于依赖关系执行相同顺序的夹具
import pytest
@pytest.fixture
def order():
    return []
@pytest.fixture
def a(order):
    order.append("a")
@pytest.fixture
def b(a, order):
    order.append("b")
@pytest.fixture
def c(a, b, order):
    order.append("c")
@pytest.fixture
def d(c, b, order):
    order.append("d")
@pytest.fixture
def e(d, b, order):
    order.append("e")
@pytest.fixture
def f(e, order):
    order.append("f")
@pytest.fixture
def g(f, c, order):
    order.append("g")

def test_order(g, order):
    assert order == ["a", "b", "c", "d", "e", "f", "g"]
3、固定装置首先在其范围内执行

示例1:

import pytest
@pytest.fixture(scope="class")
def order():
    return []
@pytest.fixture(scope="class", autouse=True)
def c1(order):
    order.append("c1")
@pytest.fixture(scope="class")
def c2(order):
    order.append("c2")
@pytest.fixture(scope="class")
def c3(order, c1):
    order.append("c3")
class TestClassWithC1Request:
    def test_order(self, order, c1, c3):
        assert order == ["c1", "c3"]
class TestClassWithoutC1Request:
    def test_order(self, order, c2):
        assert order == ["c1", "c2"]


示例2:

import pytest
@pytest.fixture
def order():
    return []
@pytest.fixture
def c1(order):
    order.append("c1")
@pytest.fixture
def c2(order):
    order.append("c2")

class TestClassWithAutouse:
    
    @pytest.fixture(autouse=True)
    def c3(self, order, c2):
        order.append("c3")

    def test_req(self, order, c1):
        assert order == ["c2", "c3", "c1"]
    
    def test_no_req(self, order):
        assert order == ["c2", "c3"]

class TestClassWithoutAutouse:
    
    def test_req(self, order, c1):
        assert order == ["c1"]
    
    def test_no_req(self, order):
        assert order == []

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/607084.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-14
下一篇 2022-04-14

发表评论

登录后才能评论

评论列表(0条)

保存