【问题标题】:Model instance fixtures not persisted on the database模型实例夹具未保存在数据库中
【发布时间】:2016-03-08 13:45:27
【问题描述】:

我有一个包含两个方法的测试类,并希望在两个方法之间共享一个保存的模型实例。

我的灯具:

@pytest.fixture(scope='class')
def model_factory():
    class ModelFactory(object):
        def get(self):
            x = Model(email='test@example.org',
                      name='test')
            x.save()
            return x
    return ModelFactory()

@pytest.fixture(scope='class')
def model(model_factory):
    m = model_factory.get()
    return m

我的期望是在(两种)我的测试方法上只收到model 固定装置,并让它保持不变,并保存在数据库中:

@pytest.mark.django_db
class TestModel(object):

    def test1(self, model):
        assert model.pk is not None
        Model.objects.get(pk=model.pk)  # Works, instance is in the db

    def test2(self, model):
        assert model.pk is not None     # model.pk is the same as in test1
        Model.objects.get(pk=model.pk)  # Fails:
        # *** DoesNotExist: Model matching query does not exist

我已经使用--pdb 验证,在test1 结束时,运行Model.objects.all() 会返回我创建的单个实例。同时,psql 显示没有记录:

test_db=# select * from model_table;
 id | ··· fields
(0 rows)

test2 末尾的pdb 中运行Model.objects.all() 会返回一个空列表,考虑到该表是空的,这可能是正确的。

  1. 为什么我的模型没有被持久化,而查询仍然返回一个实例?
  2. 如果我的model 夹具标记为scope='class' 并保存,为什么第二个测试中查询没有返回实例? (这是我最初的问题,直到我发现保存模型对数据库没有任何作用)

使用django 1.6.1pytest-django 2.9.1pytest 2.8.5

谢谢

【问题讨论】:

    标签: django pytest pytest-django


    【解决方案1】:

    测试必须相互独立。为了确保这一点,Django - 像大多数框架一样 - 在每次测试后清除数据库。见the documentation

    【讨论】:

    • 谢谢丹尼尔,我怀疑是这样的。 @rnevius 我一直在使用 --reuse-db 选项来 pytest 以避免重新创建数据库,但是测试运行程序仍然会在各个测试运行之间刷新数据,这让我感到困惑,我想 --keepdb 会产生相同的效果。
    【解决方案2】:

    通过查看 postgres 日志,我发现 pytest-django 默认情况下会在每次测试后执行 ROLLBACK 以保持干净(这是有道理的,因为测试不应该依赖于可能被早期测试修改的状态) .

    通过用django_db(transaction=True) 装饰测试类,我确实可以看到psql 在每次测试结束时提交的数据,这回答了我的第一个问题。

    和以前一样,测试运行器确保在测试之间不保留任何状态,这是我第二点的答案。

    【讨论】:

      【解决方案3】:

      在这种情况下,范围参数有点误导,但是如果您要这样编写代码:

      @pytest.fixture(scope='class')
          def model_factory(db, request):
              # body
      

      然后你会得到一个错误,基本上说数据库夹具必须用'function'范围实现。

      我想补充一点,这目前正在开发中,将来可能会成为一个致命的功能;)github pull request

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-13
        • 2020-07-11
        • 1970-01-01
        • 2018-09-22
        • 1970-01-01
        相关资源
        最近更新 更多