模型实例 fixtures 未保存在数据库中
Model instance fixtures not persisted on the database
我有一个测试 class 有两种方法,我想在两种方法之间共享一个保存的模型实例。
我的固定装置:
@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()
returns 我创建的单个实例的末尾。同时,psql 显示没有记录:
test_db=# select * from model_table;
id | ··· fields
(0 rows)
运行 test2
末尾的 pdb 中的 Model.objects.all()
returns 一个空列表,考虑到 table 是空的,这大概是正确的.
- 为什么我的模型没有被持久化,而查询仍然是 returns 一个实例?
- 如果我的
model
夹具被标记为 scope='class'
并保存,为什么在第二次测试中查询没有返回实例? (这是我最初的问题,直到我发现保存模型对数据库没有任何作用)
使用 django 1.6.1
、pytest-django 2.9.1
、pytest 2.8.5
谢谢
测试必须相互独立。为了确保这一点,Django - 像大多数框架一样 - 在每次测试后清除数据库。参见 the documentation。
通过查看 postgres 日志,我发现 pytest-django
默认情况下会在每次测试后执行 ROLLBACK
以保持干净(这是有道理的,因为测试不应该依赖于状态可能被早期测试修改过)。
通过用 django_db(transaction=True)
装饰测试 class 我确实可以从 psql 中看到每个测试结束时提交的数据,这回答了我的第一个问题。
和以前一样,测试运行器确保在测试之间不保留任何状态,这是我第二点的答案。
Scope 参数在这种情况下有点误导,但是如果您这样编写代码:
@pytest.fixture(scope='class')
def model_factory(db, request):
# body
然后你会得到一个错误,基本上说数据库夹具必须在 'function' 范围内实现。
我想补充一点,这目前正在开发中,将来可能会成为一个杀手级功能;)github pull request
我有一个测试 class 有两种方法,我想在两种方法之间共享一个保存的模型实例。
我的固定装置:
@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()
returns 我创建的单个实例的末尾。同时,psql 显示没有记录:
test_db=# select * from model_table;
id | ··· fields
(0 rows)
运行 test2
末尾的 pdb 中的 Model.objects.all()
returns 一个空列表,考虑到 table 是空的,这大概是正确的.
- 为什么我的模型没有被持久化,而查询仍然是 returns 一个实例?
- 如果我的
model
夹具被标记为scope='class'
并保存,为什么在第二次测试中查询没有返回实例? (这是我最初的问题,直到我发现保存模型对数据库没有任何作用)
使用 django 1.6.1
、pytest-django 2.9.1
、pytest 2.8.5
谢谢
测试必须相互独立。为了确保这一点,Django - 像大多数框架一样 - 在每次测试后清除数据库。参见 the documentation。
通过查看 postgres 日志,我发现 pytest-django
默认情况下会在每次测试后执行 ROLLBACK
以保持干净(这是有道理的,因为测试不应该依赖于状态可能被早期测试修改过)。
通过用 django_db(transaction=True)
装饰测试 class 我确实可以从 psql 中看到每个测试结束时提交的数据,这回答了我的第一个问题。
和以前一样,测试运行器确保在测试之间不保留任何状态,这是我第二点的答案。
Scope 参数在这种情况下有点误导,但是如果您这样编写代码:
@pytest.fixture(scope='class')
def model_factory(db, request):
# body
然后你会得到一个错误,基本上说数据库夹具必须在 'function' 范围内实现。
我想补充一点,这目前正在开发中,将来可能会成为一个杀手级功能;)github pull request