2011-08-11 20 views
26

Tengo un modelo con managed = False.Cómo crear una tabla durante las pruebas de Django con managed = False

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

    class Meta: 
     managed = False 

que tienen una prueba de unidad que crea un SampleModel, sin embargo cuando funciono con la prueba me sale:

DatabaseError: no such table: SAMPLE_SAMPLE_MODEL 

Los documentos django - https://docs.djangoproject.com/en/dev/ref/models/options/#managed documenta lo siguiente:

Para las pruebas involucrando modelos con managed = False, depende de usted asegurarse de que se creen las tablas correctas como parte de la configuración de la prueba.

¿Cómo puedo "crear" las tablas durante la configuración de la prueba? O, como alternativa, ¿cómo puedo hacerlo de modo que cuando estoy ejecutando pruebas, este modelo tenga "managed = True" durante la prueba?

En la aplicación real, este modelo está respaldado por una vista en la base de datos. Sin embargo, durante el examen, me gustaría tratar esto como una tabla y poder insertar datos de prueba allí.

Respuesta

13

Mira esta publicación de blog: http://www.caktusgroup.com/blog/2010/09/24/simplifying-the-testing-of-unmanaged-database-models-in-django/ Describe en detalle la creación de un corredor de prueba para modelos no administrados.

+1

No funciona para Django 1.11 (ya que usará las migraciones para crear la base de datos de prueba, y siguiendo la definición de su modelo establecerá 'managed = False'). La solución propuesta en https://stackoverflow.com/a/37060122/462655 funciona para Django 1.11 – msonsona

+0

FWIW Esto tampoco funciona en Django 1.10.7 (y posiblemente toda la serie 1.10.x, pero no estoy seguro) . –

+0

Hay disponible una actualización de la idea original del corredor de pruebas en https://dev.to/patrnk/testing-against-unmanaged-models-in-django – shadi

4

de ejecución de SQL prima para crear la tabla en la configuración de la prueba:

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

Se puede utilizar un comando de volcado que sólo incluye las definiciones de tabla, y úsala en el método 'setUp()' de esta respuesta. Por ejemplo, en el caso de MySQL, el comando sería algo así como 'mysqldump --no-data databasename'. –

+0

Las tablas 'CREATE' y' DROP' para cada prueba son lentas. El esquema nunca cambia entre pruebas. –

2

Crear su propio corredor de prueba utilizando la siguiente:

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 

Luego de la configuración de agregar esta clase a TEST_RUNNER.

1

Una solución rápida si usted no tiene muchas mesas no administrados:

Primera añadir una nueva variable a la configuración.

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

entonces en los modelos

# 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

Niza enchufe y solución de juego. Simplemente pegue esto antes de la definición de la clase de prueba. (Nota: Django 1.8 usa)

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

sólo para añadir: django.db.models.loading.get_models serán eliminados en Django 1.9 (ver https://github.com/BertrandBordage/django-cachalot/issues/33).

a continuación es un uno actualizado para 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 

Nota también hay que tomar las migraciones de atención (ver Testing django application with several legacy databases)

MIGRATION_MODULES = { 
    'news': 'news.test_migrations', 
    'economist': 'economist.test_migrations' 
} 
Cuestiones relacionadas