2011-08-11 12 views
26

Mam model z managed = False.Jak utworzyć tabelę podczas testów Django z managed = False

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

    class Meta: 
     managed = False 

mam badanej jednostki, która tworzy SampleModel, jednak gdy uruchamiam test uzyskać:

DatabaseError: no such table: SAMPLE_SAMPLE_MODEL 

Docs django - https://docs.djangoproject.com/en/dev/ref/models/options/#managed dokumentuje następujące:

Dla testów w przypadku modeli z managed = False, od Ciebie zależy, czy poprawne tabele zostaną utworzone w ramach konfiguracji testowej.

Jak mogę "tworzyć" tabele podczas konfiguracji testu? Lub alternatywnie, jak mogę to zrobić, aby podczas testowania ten model miał "managed = True" na czas trwania testu?

W prawdziwej aplikacji ten model jest faktycznie wspierany przez widok w bazie danych. Jednak w trakcie testu chciałbym traktować to jako tabelę i móc tam wstawiać dane testowe.

Odpowiedz

13

Zobacz ten wpis na blogu: http://www.caktusgroup.com/blog/2010/09/24/simplifying-the-testing-of-unmanaged-database-models-in-django/ Opisuje szczegółowo tworzenie biegacza testowego dla modeli niezarządzanych.

+1

Nie działa dla Django 1.11 (ponieważ będzie używał migracji do utworzenia testowej bazy danych, a po definicji twojego modelu ustawi się 'managed = False'). Rozwiązanie zaproponowane w https://stackoverflow.com/a/37060122/462655 działa dla Django 1.11 – msonsona

+0

FWIW to również nie działa w Django 1.10.7 (i prawdopodobnie całej serii 1.10.x, ale nie jestem pewien) . –

+0

Aktualizacja pierwotnego pomysłu na testowanie jest dostępna na stronie https://dev.to/patrnk/testing-against-unmanaged-models-in-django – shadi

4

Execute surowego SQL do tworzenia tabeli w konfiguracji testowej:

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

Można użyć polecenia dump, który zawiera tylko definicje tabel, i użyj go w metodzie 'setUp()' tej odpowiedzi. Na przykład w przypadku MySQL, komenda byłaby podobna do 'mysqldump --no-data databasename'. –

+0

Stoły 'CREATE' i' DROP' dla każdego pojedynczego testu są wolne. Schemat nigdy nie zmienia się między testami. –

2

Stwórz własną testową biegacza za pomocą tego:

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 

Następnie w ustawieniach dodać tę klasę TEST_RUNNER.

1

szybko naprawić, jeśli nie mają wiele niezarządzanymi tabele:

Pierwszy dodać nową zmienną do ustawień.

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

następnie w modelach

# 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

Nicea rozwiązanie plug and-play. Po prostu wklej to przed definicją klasy testowej. (Uwaga: django 1.8 używany)

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

Wystarczy dodać: django.db.models.loading.get_models zostaną usunięte w Django 1.9 (patrz https://github.com/BertrandBordage/django-cachalot/issues/33).

Poniżej jest zaktualizowana po jednym dla Django 1.10:

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 

Uwaga trzeba także wziąć migracje opieki (patrz Testing django application with several legacy databases)

MIGRATION_MODULES = { 
    'news': 'news.test_migrations', 
    'economist': 'economist.test_migrations' 
} 
Powiązane problemy