python - 具有 session 范围的 PyTest fixture 不保持数据库数据的连续性

标签 python django testing pytest

此测试 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/

相关文章:

Golang : reflect. DeepEqual 返回意外的 false

python - Pandas 中令人困惑的关键错误

python - pulp.solvers.PulpSolverError : PuLP: cannot execute glpsol. exe

Python:打开具有定义的驱动器盘符的文件 - TypeError:需要整数

python - 为什么 vim 红色突出显示 Django 模板中的结束标签?

spring - 测试 Maven 模块中的 FileNotFoundException

Python:结合使用集合和字典

python - 如何在 Django 生产环境中提供媒体文件?

python - Django 模型表单未生成预期的 HTML

c# - 如何为 WPF 命令绑定(bind)编写测试?