通过以下夹具和测试,测试通过: 来自deals.models进口交易
@pytest.fixture(scope='function')
def myfixture(django_db_blocker):
with django_db_blocker.unblock():
new_deal = Deal()
new_deal.name = 'Alice'
new_deal.save()
@pytest.mark.django_db
def test_1(myfixture):
print(myfixture)
deals = Deal.objects.all()
assert deals
@pytest.mark.django_db
def test_2(myfixture):
print(myfixture)
deals = Deal.objects.all()
assert deals
结果:
============ test session starts =============
myapp/tests/pytest_test.py::test_1 PASSED
myapp/tests/pytest_test.py::test_2 PASSED
但如果我将范围更改为'module',则第二个失败:
@pytest.fixture(scope='module')
def myfixture(django_db_blocker):
with django_db_blocker.unblock():
load_deals()
结果:
============ test session starts =============
myapp/tests/pytest_test.py::test_1 PASSED
myapp/tests/pytest_test.py::test_2 FAILED
问题在于DB没有被持久化,因为我可以看到我可以访问创建的交易,如果我在夹具中返回它,但数据库是空的。
========= FAILURES =========
_________ test_2 _________
myfixture = id: 1, name='Alice'
@pytest.mark.django_db
def test_2(myfixture):
print(myfixture)
deals = Deal.objects.all()
> assert deals
E assert <QuerySet []>
如果我只运行test_2,它当然有效:
============ test session starts =============
myapp/tests/pytest_test.py::test_2 PASSED
我有很多共享相同灯具的测试,如果灯具只能运行一次因为load_deals()非常慢,那么速度会快很多。
看起来我可以重用名称django_db_setup作为fixture,而scope ='session'可以工作,但我需要根据测试运行不同的灯具。
我正在使用python 3.6.1 - pytest 3.1.2 - pytest-django 3.1.2 with mariadb 10.1
关于如何使这项工作的任何想法?
答案 0 :(得分:0)
看起来不像是pytest问题。
这个对象Deal
是什么?看看它的类实现。
另请查看您的数据库功能和函数load_deals()
定义。
尝试添加一些日志记录,以便在调用Deal.objects
Deal.objects.all()
是否发生了更改
那些Deal.objects可能是generator
的实例吗? (python中的生成器是disposable
(仅供一次性使用)对象:
>>> g = ( i for i in range(20))
>>> g
<generator object <genexpr> at 0x101a16f10>
>>> [i for i in g]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> [i for i in g] # g "has nothing to give"
[]
另请参阅此答案:Why can't I iterate twice over the same data?
@ludofet好吧,我现在看到来自django的文档 - Deal.objects.all()将返回一个QuerySet对象,该对象是来自iterable的子类 - 这是一个“单用对象”,意味着你不能在它上面迭代两次。因此,使用Deal对象的第一个测试将通过,第二个将不会在其中找到任何数据。当您的fixture具有范围“函数”时,您的测试会通过,因为fixture会为每个测试创建新的Deal对象,因此您只迭代它一次。 https://docs.djangoproject.com/en/1.11/ref/models/querysets/#all https://docs.djangoproject.com/en/1.11/ref/models/querysets/#django.db.models.query.QuerySet