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

Python 链接测试并将对象从一个测试传递到另一个测试,python,pytest,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 cre

我试图在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
(在我们进一步讨论之前,我知道——但是关于这个问题的单一答案是离题的,而这个问题本身已经有2年历史了)


使用这样的固定装置感觉不太干净。。。如果第一次测试失败,行为也不清楚(尽管可以通过测试fixture的内容或使用pytest文档中的增量fixture和下面的注释来补救)。有没有更好/更规范的方法来实现这一点?

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

#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
名称空间 通过命名空间共享数据的示例。通过钩子在
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'
隐藏物 缓存是一个整洁的特性,因为它在测试运行之间被保存在磁盘上,所以当重用一些长时间运行的任务的结果以节省重复测试运行的时间时,它通常很方便,但是您也可以使用它在测试之间共享数据。缓存对象可通过
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'
理想情况下,只有在前一个测试成功的情况下才能运行此测试

这有一个插件:。例如:

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 =====================

我会说,在测试中传递东西是个坏主意,因为它超出了单元测试的目的。无论如何,你可以使用这里描述的东西来运行一个测试,前提是前一个测试成功。是的,我知道单元测试应该做什么。但是,您建议我如何在不首先创建对象的情况下测试对象的删除?(我不是轻率的-如果有一个标准的、最佳实践的方法来做我感兴趣的这类测试。目前我能想到的最好办法是将在创建测试中创建的对象重新用作删除测试的固定装置)您创建了一个带有对象的固定装置,希望它对其他测试也有用(功能范围)然后删除该对象。然后分别测试创建。只是一个观察(可能与尝试提供MCVE有关),请记住,您的
test\u put\u stuff
并不是真正的测试,而是作为某种扩展夹具工作。我知道,第二个片段只是一个PoC,用于查看夹具是否可写。我将把这两个代码片段合并在一起,以使其更清晰。这与我想要的非常接近,只是
test\u creation()
最终被调用了两次。由于这些测试有副作用(在我的上下文中是不幸但不可避免的),这是我宁愿避免的。你能让id变量处于创建状态而不是更新状态吗?我不确定我是否理解你的问题。请检查原始问题,我已将其更新为更具体的问题,看起来像我需要的!感谢
pytest\u命名空间
无需更换。我们刚刚将属性添加到
\uuuuuuuuuuuuuu类