Pytest-django: Bagaimana cara mengizinkan akses basis data secara global tanpa menggunakan tanda Django_db?

Dibuat pada 20 Sep 2016  ·  8Komentar  ·  Sumber: pytest-dev/pytest-django

Saya berjuang untuk mengonversi tes berbasis pelari uji Django saya ke pytest.
Saya mengharapkan puting itu

import pytest
pytestmark = pytest.mark.django_db

ke modul terakhir dari stacktrace milik kode saya (lib/frontend/decorators.py)
akan mengurangi ini, tapi tidak. Menempatkannya ke dalam keempat modul saya di stacktrace juga tidak membantu.

Apakah ada cara saya dapat mengizinkan akses basis data secara global di 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.

Komentar yang paling membantu

Nah, Anda selalu dapat membuat perlengkapan penggunaan otomatis, seperti

@pytest.fixture(autouse=True)
def enable_db_access(db):
    pass

dalam kontes Anda

Semua 8 komentar

Nah, Anda selalu dapat membuat perlengkapan penggunaan otomatis, seperti

@pytest.fixture(autouse=True)
def enable_db_access(db):
    pass

dalam kontes Anda

Jawaban @enkore adalah caranya. Saya baru saja menambahkan FAQ dalam dokumentasi juga:

http://pytest-django.readthedocs.io/en/latest/faq.html#how -can-i-give-database-access-to-all-my-tests-without-the-Django-db-marker

Modul yang saya impor dalam pengujian terhubung ke DB pada waktu impor. Bagaimana cara mengaktifkan akses DB secara global sehingga sudah diizinkan selama pengumpulan tes? Terima kasih!

@Telofy apakah Anda pernah memecahkan masalah menandai impor dengan akses db? Punya masalah yang sama...

Maaf, tetapi cara kerja Django (dan pytest-Django) tidak mungkin dengan cara yang dapat diandalkan. Satu-satunya solusi yang tepat adalah tidak melakukan kueri basis data selama waktu impor. pytest-Django dibangun di sekitar sistem perlengkapan pytests dan tidak ada cara pytest-Django dapat memastikan bahwa perlengkapan dijalankan sebelum impor.

Lihat komentar saya di sini untuk penjelasan lebih rinci tentang masalah ini:
https://github.com/pytest-dev/pytest-Django/issues/499#issuecomment -322056315

Bukan wewenang atau anggaran waktu saya untuk hanya menulis ulang seluruh platform perusahaan untuk menghindari pertanyaan-pertanyaan itu. Solusi saya adalah patching monyet yang sangat jelek di 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

Saya juga menggunakan dekorator ini (bersama dengan @pytest.mark.django_db ) untuk kemudian memastikan tes tidak berjalan pada database yang salah, karena agak rumit untuk diprediksi:

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

Terima kasih untuk contohnya @Telofy - itu sangat berguna. Saya juga ingin menghindari penulisan ulang seluruh basis kode kami!

Membuat kueri db pada waktu impor tidak hanya menyebabkan pytest yang buruk, itu akan menyebabkan masalah di bagian lain yang akan sulit dilacak. Anda akan memiliki waktu yang buruk.

Anda tidak perlu menulis ulang seluruh basis kode Anda, Anda dapat menyiasatinya menggunakan metode/properti malas. Kode yang tidak membuat koneksi sampai ditanya nilainya. Juga melewati hanya querysets tanpa mengevaluasi akan bekerja. Menghindari hal-hal seperti menghitung dll

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

tolomea picture tolomea  ·  6Komentar

WoLpH picture WoLpH  ·  7Komentar

asfaltboy picture asfaltboy  ·  5Komentar

clintonb picture clintonb  ·  4Komentar

dan-passaro picture dan-passaro  ·  4Komentar