أنا أعاني من أجل تحويل الاختبارات المعتمدة على عداء Django إلى pytest.
أتوقع أن وضع
import pytest
pytestmark = pytest.mark.django_db
في الوحدة الأخيرة من stacktrace التي تنتمي إلى الكود الخاص بي (lib / frontend / decorators.py)
من شأنه أن يخفف من هذا ، لكنه لم يفعل. لم يساعد أيضًا وضعه في الوحدات النمطية الأربعة الخاصة بي على نظام المكدس.
هل هناك أي طريقة يمكنني من خلالها السماح بالوصول إلى قاعدة البيانات عالميًا في pytest-django؟
vagrant@vagrant-ubuntu-trusty-64:/vagrant$ pytest
== test session starts ==
platform linux2 -- Python 2.7.6, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
Django settings: patient.settings (from ini file)
rootdir: /vagrant, inifile: pytest.ini
plugins: django-3.0.0, pythonpath-0.7.1
collected 265 items / 2 errors
[...]
_ ERROR collecting lib/tests/report/testfunc.py _
lib/tests/report/testfunc.py:6: in <module>
from report.func import generate_report_filename
lib/report/func.py:29: in <module>
from frontend import chart
lib/frontend/chart.py:294: in <module>
@pytest.mark.django_db
lib/frontend/decorators.py:20: in decorator
if Site.objects.get_current().id in (allowed_site_ids):
/usr/local/lib/python2.7/dist-packages/django/contrib/sites/models.py:60: in get_current
return self._get_site_by_id(site_id)
/usr/local/lib/python2.7/dist-packages/django/contrib/sites/models.py:39: in _get_site_by_id
site = self.get(pk=site_id)
/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py:127: in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
/usr/local/lib/python2.7/dist-packages/django/db/models/query.py:328: in get
num = len(clone)
/usr/local/lib/python2.7/dist-packages/django/db/models/query.py:144: in __len__
self._fetch_all()
/usr/local/lib/python2.7/dist-packages/django/db/models/query.py:965: in _fetch_all
self._result_cache = list(self.iterator())
/usr/local/lib/python2.7/dist-packages/django/db/models/query.py:238: in iterator
results = compiler.execute_sql()
/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py:838: in execute_sql
cursor = self.connection.cursor()
/usr/local/lib/python2.7/dist-packages/django/db/backends/base/base.py:162: in cursor
cursor = self.make_debug_cursor(self._cursor())
/usr/local/lib/python2.7/dist-packages/django/db/backends/base/base.py:135: in _cursor
self.ensure_connection()
E Failed: Database access not allowed, use the "django_db" mark to enable it.
حسنًا ، يمكنك دائمًا إنشاء تركيبات آلية ، مثل
@pytest.fixture(autouse=True)
def enable_db_access(db):
pass
في conftest الخاص بك
إجابةenkore هي السبيل للذهاب. لقد أضفت للتو الأسئلة الشائعة في الوثائق أيضًا:
http://pytest-django.readthedocs.io/en/latest/faq.html#how -can-i-give-database-access-to-all-my-tests-without-the-django-db-marker
الوحدة النمطية التي أقوم باستيرادها في اختبار تتصل بقاعدة البيانات في وقت الاستيراد. كيف يمكنني تمكين الوصول إلى قاعدة البيانات عالميًا بحيث يكون مسموحًا به بالفعل أثناء مجموعة الاختبار؟ شكرا!
Telofy هل سبق لك حل مشكلة تمييز الواردات بوصول db؟ لديك نفس المشكلة ...
آسف ، ولكن الطريقة التي يعمل بها Django (و pytest-django) غير ممكنة بطريقة موثوقة. الحل الوحيد المناسب هو ببساطة عدم القيام باستعلامات قاعدة البيانات أثناء وقت الاستيراد. تم بناء pytest-django حول نظام تركيبات pytest ولا توجد طريقة يمكن لـ pytest-django ضمان تشغيل التركيبات قبل الاستيراد.
انظر تعليقي هنا للحصول على شرح أكثر تفصيلاً لهذه المشكلة:
https://github.com/pytest-dev/pytest-django/issues/499#issuecomment -322056315
ليس في حدود سلطتي أو ميزانيتي الزمنية أن أعيد كتابة النظام الأساسي للشركة بالكامل لتجنب هذه الاستفسارات. الحل الخاص بي هو الترقيع القبيح للغاية للقرد في Conftest.py:
from pytest_django.plugin import _blocking_manager
from django.db.backends.base.base import BaseDatabaseWrapper
_blocking_manager.unblock()
_blocking_manager._blocking_wrapper = BaseDatabaseWrapper.ensure_connection
أنا أستخدم أيضًا هذا المصمم (جنبًا إلى جنب مع @pytest.mark.django_db
) للتأكد بعد ذلك من أن الاختبارات لا تعمل على قاعدة البيانات الخاطئة ، لأنه كان من الصعب بعض الشيء التنبؤ بما يلي:
def assert_test_db(func):
@wraps(func)
def wrapper(*args, **kwargs):
assert connection.settings_dict['NAME'] == 'test_kf_server', connection.settings_dict
return func(*args, **kwargs)
return wrapper
شكرًا على مثال Telofy - هذا مفيد حقًا. أود أيضًا تجنب إعادة كتابة قاعدة التعليمات البرمجية بالكامل!
لا يؤدي إجراء استعلامات db في وقت الاستيراد فقط إلى الآفات السيئة ، بل سيؤدي إلى حدوث مشكلات في أجزاء أخرى يصعب تعقبها. سيكون لديك وقت سيء.
لست مضطرًا إلى إعادة كتابة قاعدة التعليمات البرمجية بالكامل ، يمكنك الالتفاف حولها باستخدام طرق / خصائص كسولة. رمز لا يقوم بإجراء اتصال حتى يُطلب منك القيمة. كما أن تمرير مجموعات طلبات البحث فقط دون تقييم سوف ينجح. تجنب أشياء مثل العد وما إلى ذلك
التعليق الأكثر فائدة
حسنًا ، يمكنك دائمًا إنشاء تركيبات آلية ، مثل
في conftest الخاص بك