kur*_*tgn 5 django pytest pytest-django
我需要在使用夹具后显式删除它。我知道 pytest-django 默认情况下会在拆卸时删除所有对象,但在这种特殊情况下,我需要手动执行此操作。然而,虽然我的测试被标记为pytest.mark.django_db,但我能够创建一个固定装置,但无法在一行后删除它yield:
import pytest
from tgapps.models import TelegramApp
@pytest.fixture(scope='module')
def some_fixture():
app = TelegramApp.objects.create(
session_data=b'\xa2\x8f#',
app_owner_phone=79856235474,
app_id=182475,
app_hash='aad9ab4384fea1af0342b77b606d13b0'
)
yield app
print('deleting object...')
app.delete()
class TestTelegramServiceObject(object):
@pytest.mark.django_db
def test1(self, some_fixture):
print('Fixture created:')
print(some_fixture)
Run Code Online (Sandbox Code Playgroud)
这是我的测试输出:
============================= test session starts ==============================
platform darwin -- Python 3.6.4, pytest-3.4.0, py-1.5.2, pluggy-0.6.0
Django settings: inviter.settings.staging (from ini file)
rootdir: /Users/1111/_projects/fasttrack/inviter, inifile: pytest.ini
plugins: mock-1.7.1, dotenv-0.1.0, django-3.1.2
collected 1 item
test_example.py E.Fixture created:
<79856235474 - 182475>
deleting object...
tests/api/test_example.py:25 (TestTelegramServiceObject.test1)
@pytest.fixture(scope='module')
def some_fixture():
app = TelegramApp.objects.create(
session_data=b'\xa2\x8f#',
app_owner_phone=79856235474,
app_id=182475,
app_hash='aad9ab4384fea1af0342b77b606d13b0'
)
yield app
print('deleting object...')
> app.delete()
test_example.py:21:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/Users/1111/.virtualenvs/inviter-WB5rPISo/lib/python3.6/site-packages/django/db/models/base.py:890: in delete
collector.collect([self], keep_parents=keep_parents)
/Users/1111/.virtualenvs/inviter-WB5rPISo/lib/python3.6/site-packages/django/db/models/deletion.py:221: in collect
elif sub_objs:
/Users/1111/.virtualenvs/inviter-WB5rPISo/lib/python3.6/site-packages/django/db/models/query.py:276: in __bool__
self._fetch_all()
/Users/1111/.virtualenvs/inviter-WB5rPISo/lib/python3.6/site-packages/django/db/models/query.py:1179: in _fetch_all
self._result_cache = list(self._iterable_class(self))
/Users/1111/.virtualenvs/inviter-WB5rPISo/lib/python3.6/site-packages/django/db/models/query.py:53: in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
/Users/1111/.virtualenvs/inviter-WB5rPISo/lib/python3.6/site-packages/django/db/models/sql/compiler.py:1062: in execute_sql
cursor = self.connection.cursor()
/Users/1111/.virtualenvs/inviter-WB5rPISo/lib/python3.6/site-packages/django/db/backends/base/base.py:255: in cursor
return self._cursor()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <django.db.backends.postgresql.base.DatabaseWrapper object at 0x1048bf080>
name = None
def _cursor(self, name=None):
> self.ensure_connection()
E Failed: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.
Run Code Online (Sandbox Code Playgroud)
为什么是这样?以及如何在夹具拆卸时启用数据库评估?
Andreas Profous 提到的固定装置db是功能范围的,因此在这里不起作用。
你需要做的是:
@pytest.fixture(scope='module')
def some_fixture(django_db_setup, django_db_blocker):
with django_db_blocker.unblock():
app = TelegramApp.objects.create(
session_data=b'\xa2\x8f#',
app_owner_phone=79856235474,
app_id=182475,
app_hash='aad9ab4384fea1af0342b77b606d13b0'
)
yield app
with django_db_blocker.unblock():
print('deleting object...')
app.delete()
Run Code Online (Sandbox Code Playgroud)
django_db_setup确保测试数据库已设置(并准备好)以添加其他记录。django_db_blocker是db夹具用来允许函数范围内的修改的。它具有函数作用域的原因是,它的行为方式TestCase与默认单元测试框架中的方法的行为方式相同,其中记录在每次测试后回滚。这是一件好事,它确保在一个测试中修改记录不会改变其他测试的结果。
因此,在创建非函数作用域的固定装置时要非常小心,因为默认情况下您的修改不会包装在事务中并回滚。使用django_db_blocker可以让您挂钩该django_db_blocker.unblock()方法,从而消除修改数据库的障碍。这在您的非功能范围固定装置中是必需的。
| 归档时间: |
|
| 查看次数: |
3203 次 |
| 最近记录: |