ホームページ > バックエンド開発 > Python チュートリアル > Pytest-Django でのアンマネージド モデルの処理

Pytest-Django でのアンマネージド モデルの処理

Susan Sarandon
リリース: 2024-12-31 08:34:14
オリジナル
311 人が閲覧しました

Handling Unmanaged Models in Pytest-Django

アンマネージド モデルのテストの課題

Django プロジェクトでは、アンマネージド モデル、つまりメタ オプションに manage = True が設定されていないモデルに遭遇することがあります。これらのモデルでは、特にテスト設定にマネージド モデルとアンマネージド モデルが混在している場合、または複数のデータベース (例: マネージド モデルとアンマネージド モデルを含む) が含まれる場合、テストが困難になる可能性があります。

このブログ投稿では、pytest-django を使用してアンマネージド モデルをテストするアプローチを検討し、これらのシナリオを効果的に管理するのに役立つ長所、短所、および回避策を強調します。

アプローチ 1: すべてのモデルを管理対象としてマークする

テスト中に非管理モデルを処理する簡単な方法の 1 つは、それらを一時的に管理対象としてマークすることです。その方法は次のとおりです:

# Add this to conftest.py
@pytest.hookimpl(tryfirst=True)
def pytest_runtestloop():
    from django.apps import apps
    unmanaged_models = []
    for app in apps.get_app_configs():
        unmanaged_models += [m for m in app.get_models()
                             if not m._meta.managed]
    for m in unmanaged_models:
        m._meta.managed = True
ログイン後にコピー
ログイン後にコピー

注: このアプローチを機能させるには、pytest 設定 (または pytest.ini) に --no-migrations オプションを追加する必要があります

参照: スタック オーバーフロー

長所:

  • 実装が簡単です。

短所:

  • 移行テストをスキップします。複数の開発者が同じプロジェクトに取り組んでいる場合に問題が発生する可能性があります。

アプローチ 2: アンマネージド モデルを手動で作成する

また、テスト設定中にアンマネージド モデルを手動で作成することもできます。このアプローチにより、移行が確実にテストされます:

@pytest.fixture(scope="session", autouse=True)
def django_db_setup(django_db_blocker, django_db_setup):
    with django_db_blocker.unblock():
        for _connection in connections.all():
            with _connection.schema_editor() as schema_editor:
                setup_unmanaged_models(_connection, schema_editor)
        yield

def setup_unmanaged_models(connection, schema_editor):
    from django.apps import apps

    unmanaged_models = [
        model for model in apps.get_models() if model._meta.managed is False
    ]
    for model in unmanaged_models:
        if model._meta.db_table in connection.introspection.table_names():
            schema_editor.delete_model(model)
        schema_editor.create_model(model)
ログイン後にコピー
ログイン後にコピー

長所:

  • テスト ケースの一部として移行をテストします。

短所:

  • 少し複雑です。
  • transaction=True は、このアプローチでは機能しません (次のセクションで説明します)。

トランザクションテストを理解する

Pytest-django は、データベース フィクスチャ django_db および django_db(transaction=True) を提供します。それぞれの違いは次のとおりです:

django_db: テスト ケースの終了時に変更をロールバックします。つまり、データベースへの実際のコミットは行われません。

django_db(transaction=True): 変更をコミットし、各テスト ケースの後にデータベース テーブルを切り捨てます。各テストの後に切り捨てられるのはマネージド モデルのみであるため、これが、トランザクション テスト中にアンマネージド モデルに特別な処理が必要になる理由です。

テストケースの例

@pytest.mark.django_db
def test_example():
    # Test case logic here
    pass

@pytest.mark.django_db(transaction=True)
def test_transactional_example():
    # Test case logic here
    pass
ログイン後にコピー

アンマネージド モデルでトランザクション テストを機能させる

トランザクション テストではマネージド モデルのみが切り捨てられるため、テスト実行中にアンマネージド モデルを管理対象に変更できます。これにより、それらが切り捨てに確実に含まれるようになります:

# Add this to conftest.py
@pytest.hookimpl(tryfirst=True)
def pytest_runtestloop():
    from django.apps import apps
    unmanaged_models = []
    for app in apps.get_app_configs():
        unmanaged_models += [m for m in app.get_models()
                             if not m._meta.managed]
    for m in unmanaged_models:
        m._meta.managed = True
ログイン後にコピー
ログイン後にコピー

on_commit フックを使用して、transaction=True を回避する (可能な場合)

on_commit フックが関係するシナリオでは、pytest-django(>= v.4.4) のフィクスチャ django_capture_on_commit_callbacks を使用して、on_commit コールバックを直接キャプチャして実行することで、トランザクション テストの使用を回避できます。

@pytest.fixture(scope="session", autouse=True)
def django_db_setup(django_db_blocker, django_db_setup):
    with django_db_blocker.unblock():
        for _connection in connections.all():
            with _connection.schema_editor() as schema_editor:
                setup_unmanaged_models(_connection, schema_editor)
        yield

def setup_unmanaged_models(connection, schema_editor):
    from django.apps import apps

    unmanaged_models = [
        model for model in apps.get_models() if model._meta.managed is False
    ]
    for model in unmanaged_models:
        if model._meta.db_table in connection.introspection.table_names():
            schema_editor.delete_model(model)
        schema_editor.create_model(model)
ログイン後にコピー
ログイン後にコピー

参考文献

  • pytest-django ドキュメント
  • スタック オーバーフロー: アンマネージド モデルのテスト

アンマネージド モデルを処理するための他のアプローチやヒントはありますか?以下のコメント欄で共有してください!

以上がPytest-Django でのアンマネージド モデルの処理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート