Pytest-django: كيفية السماح بالوصول إلى قاعدة البيانات عالميًا دون استخدام علامات django_db؟

تم إنشاؤها على ٢٠ سبتمبر ٢٠١٦  ·  8تعليقات  ·  مصدر: pytest-dev/pytest-django

أنا أعاني من أجل تحويل الاختبارات المعتمدة على عداء 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 الخاص بك

ال 8 كومينتر

حسنًا ، يمكنك دائمًا إنشاء تركيبات آلية ، مثل

@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 في وقت الاستيراد فقط إلى الآفات السيئة ، بل سيؤدي إلى حدوث مشكلات في أجزاء أخرى يصعب تعقبها. سيكون لديك وقت سيء.

لست مضطرًا إلى إعادة كتابة قاعدة التعليمات البرمجية بالكامل ، يمكنك الالتفاف حولها باستخدام طرق / خصائص كسولة. رمز لا يقوم بإجراء اتصال حتى يُطلب منك القيمة. كما أن تمرير مجموعات طلبات البحث فقط دون تقييم سوف ينجح. تجنب أشياء مثل العد وما إلى ذلك

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات