Pytest-django: django_dbマークを使用せずにデータベースアクセスをグローバルに許可するにはどうすればよいですか?

作成日 2016年09月20日  ·  8コメント  ·  ソース: pytest-dev/pytest-django

Djangoテストランナーベースのテストをpytestに変換するのに苦労しています。
私は置くことを期待します

import pytest
pytestmark = pytest.mark.django_db

私のコードに属するスタックトレースの最後のモジュール(lib / frontend /decorators.py)に
これを軽減するでしょうが、そうではありませんでした。スタックトレース上の4つのモジュールすべてにそれを入れても役に立ちませんでした。

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

あなたのコンテストで

全てのコメント8件

さて、あなたはいつでも次のような自動使用フィクスチャを作成することができます

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

あなたのコンテストで

@enkoreの答えは行く方法です。 ドキュメントにもFAQを追加しました。

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

テストでインポートするモジュールは、インポート時にDBに接続します。 テスト収集中にすでに許可されているように、DBアクセスをグローバルに有効にするにはどうすればよいですか? ありがとう!

@Telofyは、インポートをdbアクセスでマークする問題を解決したことがありますか? 同じ問題があります...

申し訳ありませんが、Django(およびpytest-django)の動作は、信頼できる方法では不可能です。 唯一の適切な解決策は、インポート時にデータベースクエリを実行しないことです。 pytest-djangoはpytestsフィクスチャシステムを中心に構築されており、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の例を

インポート時にデータベースクエリを作成すると、pytestが不良になるだけでなく、他の部分で問題が発生し、追跡が困難になります。 あなたは悪い時間を過ごすつもりです。

コードベース全体を書き直す必要はありません。怠惰なメソッド/プロパティを使用して回避できます。 値を要求されるまで接続を確立しないコード。 また、評価せずにクエリセットだけを渡すこともできます。 カウントなどを避ける

このページは役に立ちましたか?
0 / 5 - 0 評価