6

django プロジェクトのテスト ケースを作成しようとしていますが、「$ ./manage.py test」コマンドを実行すると、テスト データベースは作成されますが、テーブルは作成されず、テーブルが存在しないというエラーが発生します。どんな提案でも大歓迎です。「./manage.py inspectdb > models.py」で作成したモデルを次に示します。

class MyCustomModel(models.Model):
    name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)

    class Meta:
       managed = False
       db_table = 'MY_TABLE'
4

4 に答える 4

8

テスト中の管理されていないモデルのpytest create table

--nomigrationsをor - pytest 設定が存在する場所に追加します。pytest.inisetup.cfg

[pytest]
addopts = --nomigrations

これをトップレベルに追加しますconftest.py

@pytest.fixture(autouse=True, scope="session")
def django_test_environment(django_test_environment):
    from django.apps import apps

    get_models = apps.get_models

    for m in [m for m in get_models() if not m._meta.managed]:
        m._meta.managed = True

それは魔法を行います

于 2018-06-14T03:07:33.540 に答える
7

テーブルは管理されていない ( managed = False) ため、移行またはテスト中に自動的に作成されません。

  1. 移行中にテーブルが作成されることになっている場合は、managed = False行を削除するだけです
  2. テーブルが、移行中に作成されることが想定されていないビューまたはレガシー テーブルである場合は、テスト中にモデルを管理する必要があります。

2 で、 simple を使用している場合、manage.py test私が見つけた最善の解決策は、アンマネージド モデルのマネージド フラグを変更するテスト ランナーを追加することです。私は runners.py ファイルで次のようになります。

# Credit:
# http://birdhouse.org/blog/2015/03/25/django-unit-tests-against-unmanaged-databases/
# https://www.caktusgroup.com/blog/2010/09/24/simplifying-the-testing-of-unmanaged-database-models-in-django/

from smapi.settings import *
from django.test.runner import DiscoverRunner


class ManagedModelTestRunner(DiscoverRunner):
    """
    Test runner that automatically makes all unmanaged models in your Django
    project managed for the duration of the test run, so that one doesn't need
    to execute the SQL manually to create them.
    """

    def __init__(self, **kwargs):
        from django.apps import apps

        super(ManagedModelTestRunner, self).__init__(**kwargs)

        # for a in apps.get_apps():
        #     print("Found app %s" % (a))

        # NOTE: apps must be registered in INSTALLED_APPS in settings.py before their models appear here
        all_models = apps.get_models()
        # for m in all_models:
        #     print("Found model %s - Managed:%s" % (m, m._meta.managed))

        self.unmanaged_models = [m for m in all_models if not m._meta.managed]

    def setup_test_environment(self, *args, **kwargs):
        for m in self.unmanaged_models:
            m._meta.managed = True
            # print("Modifying model %s to be managed for testing - Managed:%s" % (m, m._meta.managed))
        super(ManagedModelTestRunner, self).setup_test_environment(*args, **kwargs)

    def teardown_test_environment(self, *args, **kwargs):
        super(ManagedModelTestRunner, self).teardown_test_environment(*args, **kwargs)
        # reset unmanaged models
        for m in self.unmanaged_models:
            m._meta.managed = False
            # print("Resetting model %s to be unmanaged - Managed:%s" % (m, m._meta.managed))

これは、次の行を settings.py に追加することで有効になります。

# Set Django's test runner to the custom class defined in runners.py
TEST_RUNNER = '<project name>.runners.ManagedModelTestRunner'

最後に、テストに pytest の使用を開始し、上記のソリューションが機能しなくなったため、今日ここにいます。一連の検索の後、上記のサンプルでクレジットされているページの 1 つへのコメントで修正を発見しました (ソース、Jan Murre のクレジット)

トリックをありがとう。私は pytest-django を使用しているため、これを自分のやり方で行う方法を見つけなければなりませんでした。

pytest-django はフィクスチャを使用します。setup_test_environment() 呼び出しを行うフィクスチャが既にあります。

したがって、「_meta.managed」を設定するには、その前にフィクスチャが必要です。自動フィクスチャはアルファベット順に実行されるように見えるため、pytest-django フィクスチャ (「_django」で始まる名前) の前に来るように、フィクスチャの名前は「__」で始まります。

@pytest.fixture(autouse=True, scope='session')
def __make_unmanaged_managed():
    from django.db.models.loading import get_models
    unmanaged_models = [m for m in get_models() if not m._meta.managed]
    for m in unmanaged_models:
        m._meta.managed = True

上記のコードを conftest.py に入れると、テストが再び機能し始めました。

于 2016-07-07T15:58:32.473 に答える
0

移行はありますか? Run python manage.py makemigrations、テスト実行中に構築されたDBはそれらを使用します。

于 2015-06-23T14:31:12.903 に答える