zer*_*dge 12 python pytest pytest-django
对于以下代码:
@pytest.fixture(scope="module")
def dummy_article(request, db):
return mixer.blend("core.article", title="this one price", internal_id=3000)
def test_article_str_method(dummy_article):
assert (
str(dummy_article)
== f"article with ID {dummy_article.internal_id} and title: {dummy_article.title}"
)
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
ScopeMismatch: You tried to access the 'function' scoped fixture 'db' with a 'module' scoped request object, involved factories
core/tests/test_article_model.py:13: def dummy_article(request, db)
Run Code Online (Sandbox Code Playgroud)
如果我将夹具更改为 use scope="function",错误就会消失,但这违背了将其用于其他测试而不必为每个测试“设置”的目的。
我怎样才能拥有可db访问范围大于 的装置function?
hoe*_*ing 13
该db夹具具有function一个理由范围内,所以在每个试验结束时,事务回滚确保数据库以它具有测试开始时相同的状态下放置。不过,您可以通过使用django_db_blocker夹具来在会话/模块范围内访问夹具中的数据库:
@pytest.fixture(scope='module')
def get_all_models(django_db_blocker):
with django_db_blocker.unblock():
return MyModel.objects.all()
Run Code Online (Sandbox Code Playgroud)
请注意,在会话范围内解锁数据库时,如果您在其他装置或测试中更改数据库,则需自行解决。在下面的示例中,我Foo在会话范围的装置中创建了一个实体create_foo,然后缓存会话中的查询集all_foos:
# models.py
from django.db import models
class Foo(models.Model):
name = models.CharField(max_length=16)
Run Code Online (Sandbox Code Playgroud)
# test_foo.py
import pytest
from app.models import Foo
@pytest.fixture(scope='session', autouse=True)
def create_foo(django_db_blocker):
with django_db_blocker.unblock():
Foo.objects.create(name='bar')
@pytest.fixture(scope='module')
def all_foos(django_db_blocker):
with django_db_blocker.unblock():
yield Foo.objects.all()
def test_1(all_foos):
assert all_foos.exists()
def test_2(all_foos, db):
all_foos.delete()
assert not Foo.objects.exists()
def test3(all_foos):
assert all_foos.exists()
Run Code Online (Sandbox Code Playgroud)
在之后test_2的运行,从存储在会话中的查询集all_foos将是空的,从而导致test_3失败:
test_foo.py::test_1 PASSED [ 33%]
test_foo.py::test_2 PASSED [ 66%]
test_foo.py::test_3 FAILED [100%]
========================================= FAILURES ========================================
__________________________________________ test_3 _________________________________________
all_foos = <QuerySet []>
def test_3(all_foos):
> assert all_foos.exists()
E assert False
E + where False = <bound method QuerySet.exists of <QuerySet []>>()
E + where <bound method QuerySet.exists of <QuerySet []>> = <QuerySet []>.exists
test_foo.py:28: AssertionError
Run Code Online (Sandbox Code Playgroud)
结果:如果您不想引入可以在测试中更改的全局状态,请不要在会话范围内存储引用。从数据库中查询数据并返回副本或序列化数据等。
安全使用示例:
@pytest.fixture(scope='session')
def foo_names(django_db_blocker):
with django_db_blocker.unblock():
names = list(Foo.objects.values_list('name', flat=True))
return names
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9055 次 |
| 最近记录: |