Quiero escribir una prueba unitaria para un comando de Django manage.py que realiza una operación de backend en una tabla de base de datos. ¿Cómo invocaría el comando de administración directamente desde el código?
No quiero ejecutar el comando en el shell del sistema operativo desde tests.py porque no puedo usar el entorno de prueba configurado usando la prueba manage.py (prueba de base de datos, prueba de bandeja de salida de correo electrónico ficticio, etc.)
fuente
call_command('check')
, para asegurarse de que las comprobaciones del sistema estén pasando en una prueba.En lugar de hacer el truco call_command, puede ejecutar su tarea haciendo:
from myapp.management.commands import my_management_task cmd = my_management_task.Command() opts = {} # kwargs for your command -- lets you override stuff for testing... cmd.handle_noargs(**opts)
fuente
call_command
necesito que se cargue la aplicación probadaINSTALLED_APPS
. Entre tener que cargar la aplicación solo con fines de prueba y usar esto, elegí esto.call_command
es probablemente lo que la mayoría de la gente debería probar primero. Esta respuesta me ayudó a solucionar un problema en el que necesitaba pasar nombres de tablas Unicode alinspectdb
comando. python / bash estaban interpretando los argumentos de la línea de comandos como ascii, y eso estaba bombardeando laget_table_description
llamada en profundidad en django.el siguiente código:
from django.core.management import call_command call_command('collectstatic', verbosity=3, interactive=False) call_command('migrate', 'myapp', verbosity=3, interactive=False)
... es igual a los siguientes comandos escritos en la terminal:
$ ./manage.py collectstatic --noinput -v 3 $ ./manage.py migrate myapp --noinput -v 3
Consulte ejecutar comandos de administración de los documentos de django .
fuente
La documentación de Django sobre call_command no menciona que se
out
debe redirigir asys.stdout
. El código de ejemplo debería leer:from django.core.management import call_command from django.test import TestCase from django.utils.six import StringIO import sys class ClosepollTest(TestCase): def test_command_output(self): out = StringIO() sys.stdout = out call_command('closepoll', stdout=out) self.assertIn('Expected output', out.getvalue())
fuente
Sobre la base de la respuesta de Nate, tengo esto:
def make_test_wrapper_for(command_module): def _run_cmd_with(*args): """Run the possibly_add_alert command with the supplied arguments""" cmd = command_module.Command() (opts, args) = OptionParser(option_list=cmd.option_list).parse_args(list(args)) cmd.handle(*args, **vars(opts)) return _run_cmd_with
Uso:
from myapp.management import mycommand cmd_runner = make_test_wrapper_for(mycommand) cmd_runner("foo", "bar")
La ventaja aquí es que si ha utilizado opciones adicionales y OptParse, esto lo resolverá por usted. No es del todo perfecto, y aún no canaliza los resultados, pero usará la base de datos de prueba. A continuación, puede probar los efectos de la base de datos.
Estoy seguro de que el uso del módulo simulado de Micheal Foords y también el recableado de la salida estándar durante la duración de una prueba significaría que también podría sacar más provecho de esta técnica: probar la salida, las condiciones de salida, etc.
fuente