此测试 session 正常工作:
from myapp.models import MyModel
@pytest.fixture(scope='function')
def mymodel():
return G(MyModel)
@pytest.mark.django_db
def test_mymodel_one(mymodel):
assert MyModel.objects.count() > 0
@pytest.mark.django_db
def test_mymodel_two(mymodel):
assert MyModel.objects.count() > 0
并产生这个输出:
========= test session starts =========
tests/myapp/test_pp.py::test_mymodel_one PASSED
tests/myapp/test_pp.py::test_mymodel_two PASSED
但如果我将 fixture 的范围更改为“ session ”,则测试两个失败:
========= test session starts =========
tests/myapp/test_pp.py::test_mymodel_one PASSED
tests/myapp/test_pp.py::test_mymodel_two FAILED
========= FAILURES ==============
_________ test_mymodel_two ________
tests/myapp/test_pp.py:85: in test_mymodel_two
assert MyModel.objects.count() > 0
E assert 0 > 0
创建的对象从 fixture 正确返回(我可以访问他的值)但它不再存储。 如何使用 session 范围并维护测试数据库中的存储?
最佳答案
我试图在我的测试包中复制上下文,我发现了与您暴露的相同情况。
首先,我想与大家分享两页pytest文档,我们可以从中找到这个问题的答案。 在documentation ¹ 方法的组织略有不同,实际上委托(delegate)创建 fixture 的方法在 conftest.py 中。
# content of conftest.py
@pytest.fixture(scope="session")
def smtp(...):
# the returned fixture value will be shared for
# all tests needing it
根据您的测试设置,您可以尝试将 mymodel 方法移动到 conftest 模块中。我试图将我的 fixture 生成器移动到 conftest 文件中,但由于所需的 django_db 标记,我发现了几个遍历问题,这可能与 session 范围冲突(我猜?)。
我还在示例中找到了另一个帮助 page ² pytest,其中广泛使用 session 范围用于不同的 python 模块,指出内部模块测试不可能访问在父模块的同一级别定义的相同 session 范围。
# content of a/conftest.py
import pytest
class DB:
pass
@pytest.fixture(scope="session")
def db():
return DB()
# content of a/test_db.py
def test_a1(db):
assert 0, db # to show value
# content of a/test_db2.py
def test_a2(db):
assert 0, db # to show value
如果
# content of b/test_error.py
def test_root(db): # no db here, will error out
pass
将无法通过测试,因为
The two test modules in the a directory see the same db fixture instance while the one test in the sister-directory b doesn’t see it. We could of course also define a db fixture in that sister directory’s conftest.py file. Note that each fixture is only instantiated if there is a test actually needing it (unless you use “autouse” fixture which are always executed ahead of the first test executing).
在第二个示例中,我注意到为每个测试实例化生成 fixture 的方法,即使范围设置为 session 或模块,它像函数作用域一样工作。
您使用的是哪个版本的 pytest?
可以尝试将您的 mymodel 方法从当前模块移动到 conftest 模块吗?
关于python - 具有 session 范围的 PyTest fixture 不保持数据库数据的连续性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28982386/