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.
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
Komentar yang paling membantu
Nah, Anda selalu dapat membuat perlengkapan penggunaan otomatis, seperti
dalam kontes Anda