模型实例夹具未持久存储在数据库中

时间:2016-03-08 13:45:27

标签: django pytest pytest-django

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

我的装置:

@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)

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

  1. 为什么我的模型不会被持久化,而查询仍然会返回一个实例?
  2. 如果我的model灯具标记为scope='class'并保存,为什么第二次测试中的查询不返回实例? (这是我原来的问题,直到我发现保存模型没有对数据库做任何事情)
  3. 使用django 1.6.1pytest-django 2.9.1pytest 2.8.5

    由于

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

通过查看postgres日志,我发现默认pytest-django在每次测试后都会ROLLBACK保持清洁(这是有道理的,因为测试不应该依赖可能通过早期测试修改的状态)。

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

与以前一样,测试运行器确保测试之间不保持状态,这是我第二点的答案。

答案 2 :(得分:0)

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

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

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

我想补充一点,目前正在进行此操作,将来可能会成为杀戮功能;)github pull request