链接测试并将对象从一个测试传递到另一个测试

Chaining tests and passing an object from one test to another

我试图在 pytest 中将一个测试的结果传递给另一个测试 - 或者更具体地说,在第二个测试中重用第一个测试创建的对象。 这就是我目前的做法。

@pytest.fixture(scope="module")
def result_holder:
    return []

def test_creation(result_holder):
    object = create_object()
    assert object.status == 'created' # test that creation works as expected
    result_holder.append(object.id) # I need this value for the next test

# ideally this test should only run if the previous test was successful
def test_deletion(result_holder):
    previous_id = result_holder.pop()
    object = get_object(previous_id) # here I retrieve the object created in the first test
    object.delete()
    assert object.status == 'deleted' # test for deletion

(在我们进一步讨论之前,我知道 py.test passing results of one test to another - 但该问题的唯一答案是题外话,问题本身已有 2 年历史)

像这样使用固定装置感觉不太干净...如果第一次测试失败,行为也不清楚(尽管可以通过测试固定装置的内容或使用类似增量的东西来补救fixture 在 pytest 文档和下面的评论中)。有没有 better/more 规范的方法来做到这一点?

#Use return and then call it later so it'll look like: 

def test_creation():
    object = create_object()
    assert object.status == 'created'
    return(object.id) #this doesn't show on stdout but it will hand it to what's calling it


def test_update(id):
    object = test_creation
    object.id = id
    object.update()
    assert object.status == 'updated' # some more tests

#If this is what youre thinking of there ya go

要在测试之间共享数据,您可以使用 pytest 命名空间或缓存。

命名空间

通过命名空间共享数据的示例。通过 conftest.py:

中的钩子声明 shared 变量
# conftest.py

import pytest


def pytest_namespace():
    return {'shared': None}

现在在测试中访问并重新定义它:

import pytest


def test_creation():
    pytest.shared = 'spam'
    assert True


def test_deletion():
    assert pytest.shared == 'spam'

缓存

缓存是一个巧妙的功能,因为它在测试运行之间持久保存在磁盘上,因此在重复使用某些 long-running 任务的结果时通常会派上用场,以节省重复测试运行的时间,但您也可以使用它用于在测试之间共享数据。缓存对象可通过 config 使用。您可以访问它,即通过 request fixture:

def test_creation(request):
    request.config.cache.set('shared', 'spam')
    assert True


def test_deletion(request):
    assert request.config.cache.get('shared', None) == 'spam'

ideally this test should only run if the previous test was successful

有一个插件:pytest-dependency。示例:

import pytest


@pytest.mark.dependency()
def test_creation():
    assert False


@pytest.mark.dependency(depends=['test_creation'])
def test_deletion():
    assert True

将产生:

$ pytest -v
============================= test session starts =============================
...
collected 2 items

test_spam.py::test_creation FAILED                                      [ 50%]
test_spam.py::test_deletion SKIPPED                                     [100%]

================================== FAILURES ===================================
________________________________ test_creation ________________________________

    def test_creation():
>       assert False
E       assert False

test_spam.py:5: AssertionError
===================== 1 failed, 1 skipped in 0.09 seconds =====================