2011-08-11 10 views
26

私はmanaged = Falseのモデルを持っています。テストのためにDjangoテスト中に、managed = Falseで表を作成する方法

: - https://docs.djangoproject.com/en/dev/ref/models/options/#managedは、次の書類

DatabaseError: no such table: SAMPLE_SAMPLE_MODEL 

Djangoのドキュメント:

class SampleModel(models.Model): 
    apple = models.CharField(max_length=30) 
    orange = models.CharField(max_length=30) 

    class Meta: 
     managed = False 

は、私は、テストを実行すると、しかし私が得る、SampleModelをを作成し、ユニットテストを持っています管理されたモデル= Falseの場合、 までは、テスト設定の一部として正しいテーブルが作成されていることを確認してください。

テストセットアップ中に実際にテーブルを作成するにはどうすればよいですか?あるいは、私がテストを実行しているときに、このモデルがテストの期間中「管理=真」であるようにするにはどうすればよいですか?

実際のアプリケーションでは、このモデルは実際にはデータベースのビューによってバックアップされています。しかし、テスト中は、これをテーブルとして扱い、そこにテストデータを挿入することができます。

答えて

13

http://www.caktusgroup.com/blog/2010/09/24/simplifying-the-testing-of-unmanaged-database-models-in-django/これは、アンマネージドモデル用のテストランナーの作成について詳しく説明しています。

+1

Django 1.11では動作しません(テストデータベースを作成するために移行を使用し、モデル定義に続いて 'managed = False'を設定します)。 https://stackoverflow.com/a/37060122/462655で提案されている解決策はDjango 1.11のために働きます – msonsona

+0

FWIWこれはDjango 1.10.7で動作しません(おそらくは1.10.xシリーズ全体ではありますが、 。 –

+0

元のテストランナーのアイデアへのアップデートはhttps://dev.to/patrnk/testing-against-unmanaged-models-in-djangoから入手できます – shadi

4

は、テスト・セットアップでテーブルを作成するために、生のSQLを実行します。

from django.db import connection 

class MyTest(unittest.TestCase): 
    def setUp(self): 
     connection.cursor().execute("CREATE TABLE ...") 

    def tearDown(self): 
     connection.cursor().execute("DROP TABLE ...") 
+0

、この答えの 'setUp()'メソッドで使用してください。例えば、MySQLの場合、コマンドは 'mysqldump --no-data databasename'のようなものです。 –

+0

1回のテストごとに 'CREATE'と' DROP'テーブルが遅いです。スキーマはテスト間で決して変更されません。 –

2

は、これを使用して、独自のテストランナーを作成します。

from django.test.simple import DjangoTestSuiteRunner 

class NoDbTestRunner(DjangoTestSuiteRunner): 
    """ A test runner to test without database creation """ 

    def setup_databases(self, **kwargs): 
    """ Override the database creation defined in parent class """ 
    #set manage=True for that specific database on here 

を次に設定にTEST_RUNNERにこのクラスを追加します。

1

クイックフィックスあなたは、多くの管理対象外のテーブルを持っていない場合:

最初に設定に新しい変数を追加します。モデル

# models.py 
from django.conf import settings 

class SampleModel(models.Model): 
    apple = models.CharField(max_length=30) 
    orange = models.CharField(max_length=30) 

    class Meta: 
     managed = getattr(settings, 'UNDER_TEST', False) 
2

ニースプラグアンドプレイソリューションで、その後

# settings.py 
import sys 
UNDER_TEST = (len(sys.argv) > 1 and sys.argv[1] == 'test') 

。テストクラス定義の前に貼り付けてください。 (注:1.8が使用ジャンゴ)だけ追加する

from django.db.models.loading import get_models 

def change_managed_settings_just_for_tests(): 
    """django model managed bit needs to be switched for tests."""  

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

change_managed_settings_just_for_tests() 
1

を:django.db.models.loading.get_modelsは(https://github.com/BertrandBordage/django-cachalot/issues/33を参照)ジャンゴ1.9で削除されます。以下は

は、Djangoの1.10の更新されたものです:あなたが唯一のテーブル定義を含んでdumpコマンドを使用することができますあなたもケアの移行を取る必要がある

class UnManagedModelTestRunner(DiscoverRunner): 
    ''' 
    Test runner that automatically makes all unmanaged models in your Django 
    project managed for the duration of the test run. 
    Many thanks to the Caktus Group 
    ''' 

    def setup_test_environment(self, *args, **kwargs): 
     from django.apps import apps 
     self.unmanaged_models = [m for m in apps.get_models() if not m._meta.managed] 
     for m in self.unmanaged_models: 
      m._meta.managed = True 
     super(UnManagedModelTestRunner, self).setup_test_environment(*args, **kwargs) 

    def teardown_test_environment(self, *args, **kwargs): 
     super(UnManagedModelTestRunner, self).teardown_test_environment(*args, **kwargs) 
     # reset unmanaged models 
     for m in self.unmanaged_models: 
      m._meta.managed = False 

注意(Testing django application with several legacy databasesを参照)

MIGRATION_MODULES = { 
    'news': 'news.test_migrations', 
    'economist': 'economist.test_migrations' 
} 
関連する問題