En Django 1.4, 1.5, 1.6, 1.7, o 1.8 se debe ser suficiente para utilizar:
if 'test' in sys.argv:
DATABASES['default']['ENGINE'] = 'django.db.backends.sqlite3'
No debería ser necesario anular TEST_NAME
, ni llamar al syncdb
para ejecutar pruebas. Como señala @osa, el valor predeterminado con el motor SQLite es crear la base de datos de prueba en la memoria (TEST_NAME=':memory:'
). No es necesario llamar al syncdb
porque el marco de prueba de Django lo hará automáticamente mediante una llamada al syncdb
o al migrate
según la versión de Django. Puede observar esto con manage.py test -v [2|3]
.
Muy hablando en términos generales Django configura el entorno de prueba por:
- Carga de la base de datos normal
NAME
de su settings.py
- Descubrimiento y construcción de sus clases de prueba (
__init__()
se llama)
- Ajuste de la base de datos
NAME
al valor de TEST_NAME
- Ejecutando las pruebas en contra la base de datos
NAME
Aquí está el problema: En el paso 2, NAME
todavía está señalando en su base de datos regulares (no de prueba). Si sus pruebas contienen consultas o consultas a nivel de clase en __init__()
, se ejecutarán en la base de datos normal, lo que probablemente no sea lo que usted espera. Esto se identifica en bug #21143.
No practico:
class BadFooTests(TestCase):
Foo.objects.all().delete() # <-- class level queries, and
def __init__(self):
f = Foo.objects.create() # <-- queries in constructor
f.save() # will run against the production DB
def test_foo(self):
# assert stuff
ya que éstas se ejecutan en la base de datos especificada en NAME
. Si NAME
en esta etapa apunta a una base de datos válida (por ejemplo, su base de datos de producción), la consulta se ejecutará, pero puede tener consecuencias no deseadas.Si ha anulado ENGINE
y/o NAME
tal que no apunta a una base de datos preexistente, una excepción se produce porque la base de datos de prueba aún no se ha creado:
django.db.utils.DatabaseError: no such table: yourapp_foo # Django 1.4
DatabaseError: no such table: yourapp_foo # Django 1.5
OperationalError: no such table: yourapp_foo # Django 1.6+
En lugar de hacer:
class GoodFooTests(TestCase):
def setUp(self):
f = Foo.objects.create() # <-- will run against the test DB
f.save() #
def test_foo(self):
# assert stuff
Por lo tanto, si ve errores, verifique que sus pruebas no incluyan ninguna consulta que pueda afectar la base de datos fuera de las definiciones de métodos de la clase de prueba.
[1] En Django> = 1,7, DATABASES[alias]['TEST_NAME']
es deprecated a favor de DATABASES[alias]['TEST']['NAME']
[2] Véase el método create_test_db()
en db/backends/creation.py
Dudo que esto va a funcionar. Django destruye la base de datos de prueba después de cada ejecución, así que si estás en lo correcto, necesitaría hacer un syncdb antes de cada ejecución ... – Cerin
FUNCIONA. La base de datos test-Sqlite está [en memoria de forma predeterminada] (https://docs.djangoproject.com/en/1.4/topics/testing/#the-test-database), por lo que no hay archivos para destruir después de una prueba . El archivo que crea con syncdb actúa simplemente como una plantilla para la base de datos de prueba en memoria. Un syncdb solo es necesario cuando la estructura de la base de datos cambia. –
¡Una construcción más ridícula! 'if True' siempre se ejecutará, entonces, ¿por qué perder el tiempo revisándolo? – Bobort