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

pil*_*lls 6 python pytest

我正在尝试将一个测试的结果传递给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
Run Code Online (Sandbox Code Playgroud)

(在进一步介绍之前,我知道py.test将一项测试的结果传递给另一项 -但该问题的单个答案是题外话,问题本身已有 2年历史了)

像这样使用fixtures感觉不是很干净……而且如果第一个测试失败,行为也不清楚(尽管可以通过测试fixture的内容或在pytest doc中使用增量fixture来纠正)以及下面的评论)。是否有更好/更规范的方法来做到这一点?

hoe*_*ing 8

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

命名空间

通过名称空间共享数据的示例。shared通过钩子声明变量conftest.py

# conftest.py

import pytest


def pytest_namespace():
    return {'shared': None}
Run Code Online (Sandbox Code Playgroud)

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

import pytest


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


def test_deletion():
    assert pytest.shared == 'spam'
Run Code Online (Sandbox Code Playgroud)

快取

缓存是一项很好的功能,因为它可以在两次测试之间保留在磁盘上,因此通常在重用某些长期运行的任务的结果以节省重复测试的时间时非常方便,但是您也可以使用它在测试之间共享数据。缓存对象可通过访问config。您可以通过request灯具访问它:

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


def test_deletion(request):
    assert request.config.cache.get('shared', None) == 'spam'
Run Code Online (Sandbox Code Playgroud)

理想情况下,此测试仅应在先前的测试成功的情况下运行

有一个用于该插件:pytest-dependency。例:

import pytest


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


@pytest.mark.dependency(depends=['test_creation'])
def test_deletion():
    assert True
Run Code Online (Sandbox Code Playgroud)

将产生:

$ 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 =====================
Run Code Online (Sandbox Code Playgroud)

  • `pytest_namespace` 已[在 Pytest 4.0 中删除](https://docs.pytest.org/en/latest/deprecations.html#pytest-namespace),没有替代。我们刚刚向“__class__”添加了属性。 (4认同)