2016-03-08 83 views
1

我有两个方法的测试类,并且希望在两个方法之间共享保存的模型实例。模型实例装置未在数据库中保留

我的灯具:

@pytest.fixture(scope='class') 
def model_factory(): 
    class ModelFactory(object): 
     def get(self): 
      x = Model(email='[email protected]', 
         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

感谢

回答

1

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

+0

谢谢丹尼尔,我怀疑这是事实。 @rnevius我一直在使用'--reuse-db'选项pytest以避免数据库重新创建,但测试运行器仍然在单独的测试运行之间刷新数据,这让我感到困惑,我想'--keepdb'会具有相同的效果。 – Mariano

0

通过查看日志的Postgres我发现pytest-django默认完成了一个ROLLBACK每次测试后,保持干净的东西(这是有道理的,因为测试不应该依赖于可能由早期测试修改后的状态)。

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

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

0

范围的说法是在这种情况下,一个有点误导,但是如果你会写你这样的代码:

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

,那么你会得到一个错误,基本上说,数据库夹具具有与“功能”来实现范围。

我想补充一点,这是当前正在工作并可能在将来的杀伤功能;)github pull request

相关问题