¿Existe la posibilidad de escribir django unittests sin configurar un db? Quiero probar la lógica de negocios que no requiere la configuración de db. Y aunque es rápido configurar un db, realmente no lo necesito en algunas situaciones.
126
Respuestas:
Puede subclasificar DjangoTestSuiteRunner y anular los métodos setup_databases y teardown_databases para pasar.
Cree un nuevo archivo de configuración y configure TEST_RUNNER en la nueva clase que acaba de crear. Luego, cuando esté ejecutando su prueba, especifique su nuevo archivo de configuración con el indicador --settings.
Aquí esta lo que hice:
Cree un corredor de traje de prueba personalizado similar a este:
Crea una configuración personalizada:
Cuando esté ejecutando sus pruebas, ejecútelo de la siguiente manera con el indicador --settings establecido en su nuevo archivo de configuración:
ACTUALIZACIÓN: abril / 2018
Desde Django 1.8, el módulo se movió a .
django.test.simple.DjangoTestSuiteRunner
'django.test.runner.DiscoverRunner'
Para obtener más información, consulte la sección de documentación oficial sobre corredores de prueba personalizados.
fuente
--testrunner
opción.Generalmente las pruebas en una aplicación se pueden clasificar en dos categorías
Django admite pruebas unitarias y de integración.
Las pruebas unitarias no requieren la configuración y el desmantelamiento de la base de datos, que debemos heredar de SimpleTestCase .
Para los casos de prueba de integración, heredar de TestCase a su vez hereda de TransactionTestCase y configurará y destruirá la base de datos antes de ejecutar cada prueba.
Esta estrategia asegurará que la base de datos se cree y destruya solo para los casos de prueba que acceden a la base de datos y, por lo tanto, las pruebas serán más eficientes
fuente
De
django.test.simple
Entonces anular en
DiscoverRunner
lugar deDjangoTestSuiteRunner
.Usar así:
fuente
Elegí heredar
django.test.runner.DiscoverRunner
y hacer un par de adiciones alrun_tests
método.Mi primera adición verifica si es necesario configurar una base de datos y permite que la
setup_databases
funcionalidad normal se active si es necesaria una base de datos. Mi segunda adición permiteteardown_databases
que se ejecute lo normal sisetup_databases
se permitió la ejecución del método.Mi código asume que cualquier TestCase que hereda de
django.test.TransactionTestCase
(y por lo tantodjango.test.TestCase
) requiere que se configure una base de datos. Hice esta suposición porque los documentos de Django dicen:https://docs.djangoproject.com/en/1.6/topics/testing/tools/#django.test.SimpleTestCase
mysite / scripts / settings.py
Finalmente, agregué la siguiente línea al archivo settings.py de mi proyecto.
mysite / settings.py
Ahora, cuando ejecuto solo pruebas no dependientes de db, ¡mi conjunto de pruebas ejecuta un orden de magnitud más rápido! :)
fuente
Actualizado: también vea esta respuesta para usar una herramienta de terceros
pytest
.@Cesar tiene razón. Después de ejecutarse accidentalmente
./manage.py test --settings=no_db_settings
, sin especificar el nombre de una aplicación, mi base de datos de desarrollo se borró.Para una forma más segura, use lo mismo
NoDbTestRunner
, pero junto con lo siguientemysite/no_db_settings.py
:Necesita crear una base de datos llamada
_test_mysite_db
usando una herramienta de base de datos externa. Luego ejecute el siguiente comando para crear las tablas correspondientes:Si está utilizando South, también ejecute el siguiente comando:
¡OKAY!
Ahora puede ejecutar pruebas unitarias increíblemente rápido (y seguro):
fuente
Como alternativa a la modificación de su configuración para que NoDbTestRunner sea "seguro", aquí hay una versión modificada de NoDbTestRunner que cierra la conexión de la base de datos actual y elimina la información de conexión de la configuración y el objeto de conexión. Funciona para mí, pruébalo en tu entorno antes de confiar en él :)
fuente
__getitem__
. Úseloconnections._connections.default
para acceder al objeto.Otra solución sería tener su clase de prueba simplemente heredando en
unittest.TestCase
lugar de cualquiera de las clases de prueba de Django. Los documentos de Django ( https://docs.djangoproject.com/en/2.0/topics/testing/overview/#writing-tests ) contienen la siguiente advertencia al respecto:Sin embargo, si su prueba no utiliza la base de datos, esta advertencia no tiene por qué preocuparle y puede obtener los beneficios de no tener que ejecutar cada caso de prueba en una transacción.
fuente
Las soluciones anteriores también están bien. Pero la siguiente solución también reducirá el tiempo de creación de db si hay más migraciones. Durante las pruebas unitarias, ejecutar syncdb en lugar de ejecutar todas las migraciones hacia el sur será mucho más rápido.
fuente
Mi servidor web solo permite crear y descartar bases de datos desde su GUI web, por lo que recibí un error "Tengo un error al crear la base de datos de prueba: Permiso denegado" al intentar ejecutar
python manage.py test
.Esperaba usar la opción --keepdb para django-admin.py, pero parece que ya no se admite a partir de Django 1.7.
Lo que terminé haciendo fue modificar el código de Django en ... / django / db / backends / creation.py, específicamente las funciones _create_test_db y _destroy_test_db.
Porque
_create_test_db
comenté lacursor.execute("CREATE DATABASE ...
línea y la reemplacépass
para que eltry
bloque no estuviera vacío.Para
_destroy_test_db
acabo comentadacursor.execute("DROP DATABASE
- Yo no tenía necesidad de reemplazarlo con nada porque ya había otro comando en el bloque (time.sleep(1)
).Después de eso, mis pruebas funcionaron bien, aunque configuré una versión test_ de mi base de datos regular por separado.
Por supuesto, esta no es una gran solución, porque se romperá si se actualiza Django, pero tenía una copia local de Django debido al uso de virtualenv, así que al menos tengo control sobre cuándo / si me actualizo a una versión más nueva.
fuente
Otra solución no mencionada: esto fue fácil de implementar porque ya tengo múltiples archivos de configuración (para local / puesta en escena / producción) que heredan de base.py. Así que, a diferencia de otras personas, no tuve que sobrescribir BASES DE DATOS ['predeterminado'], ya que BASES DE DATOS no está configurado en base.py
SimpleTestCase todavía intentó conectarse a mi base de datos de prueba y ejecutar migraciones. Cuando hice un archivo config / settings / test.py que no configuró BASES DE DATOS para nada, entonces las pruebas de mi unidad se ejecutaron sin él. Me permitió usar modelos que tenían clave externa y campos de restricción únicos. (La búsqueda de clave externa inversa, que requiere una búsqueda de db, falla).
(Django 2.0.6)
Fragmentos de código PS
fuente
Al usar el corredor de prueba de nariz (django-nose), puede hacer algo como esto:
my_project/lib/nodb_test_runner.py
:En su
settings.py
puede especificar el corredor de prueba allí, es decirTEST_RUNNER = 'lib.nodb_test_runner.NoDbTestRunner' . # Was 'django_nose.NoseTestSuiteRunner'
O
Lo quería solo para ejecutar pruebas específicas, así que lo ejecuto así:
fuente