Ejecutar un caso de prueba específico en Django cuando su aplicación tiene un directorio de pruebas

165

La documentación de Django ( http://docs.djangoproject.com/en/1.3/topics/testing/#running-tests ) dice que puede ejecutar casos de prueba individuales al especificarlos:

$ ./manage.py test animals.AnimalTestCase

Esto supone que tiene sus pruebas en un archivo tests.py en su aplicación Django. Si esto es cierto, entonces este comando funciona como se esperaba.

Tengo mis pruebas para una aplicación Django en un directorio de pruebas:

my_project/apps/my_app/
├── __init__.py
├── tests
   ├── __init__.py
   ├── field_tests.py
   ├── storage_tests.py
├── urls.py
├── utils.py
└── views.py

El tests/__init__.pyarchivo tiene una función suite ():

import unittest

from my_project.apps.my_app.tests import field_tests, storage_tests

def suite():
    tests_loader = unittest.TestLoader().loadTestsFromModule
    test_suites = []
    test_suites.append(tests_loader(field_tests))
    test_suites.append(tests_loader(storage_tests))
    return unittest.TestSuite(test_suites)

Para ejecutar las pruebas que hago:

$ ./manage.py test my_app

Intentar especificar un caso de prueba individual genera una excepción:

$ ./manage.py test my_app.tests.storage_tests.StorageTestCase
...
ValueError: Test label 'my_app.tests.storage_tests.StorageTestCase' should be of the form app.TestCase or app.TestCase.test_method

Traté de hacer lo que decía el mensaje de excepción:

$ ./manage.py test my_app.StorageTestCase
...
ValueError: Test label 'my_app.StorageTestCase' does not refer to a test

¿Cómo especifico un caso de prueba individual cuando mis pruebas están en varios archivos?

Hekevintran
fuente

Respuestas:

156

Pedido de Django nariz . Le permite especificar pruebas para ejecutar como:

python manage.py test another.test:TestCase.test_method

o como se señala en los comentarios, use la sintaxis:

python manage.py test another.test.TestCase.test_method
Sam Dolan
fuente
Gracias @sdolan. Encontró el mismo problema que hekevintran. Cambió a django-nose y solucionó ese problema, también funciona mucho mejor que el corredor de prueba predeterminado de Django.
LeeMobile
Esto ejecuta una prueba, pero ¿cómo ejecutar un TestCase completo?
jMyles
55
@jMyles:another.test:TestCase
Sam Dolan
44
Atención personas como yo que pegan ciegamente desde Stackoverflow: esto producirá un error sin el complemento mencionado, use la sintaxis descrita en la otra respuesta (. En lugar de :) que funciona en Django 1.6+.
Andy Smith
1
rechacé esta respuesta porque en realidad no responde la pregunta del OP, que era cómo hacer esto en Django. Más bien, solo sugiere cambiar a Nosetest
Josh Brown
175

Desde Django 1.6 puede ejecutar un caso de prueba completo, o una prueba única, utilizando la notación de puntos completa para el elemento que desea ejecutar.

El descubrimiento de prueba automático ahora encontrará pruebas en cualquier archivo que comience con la prueba en el directorio de trabajo, por lo que al abordar la pregunta, tendría que cambiar el nombre de sus archivos, pero ahora puede mantenerlos dentro del directorio que desee. Si desea utilizar nombres de archivo personalizados, puede especificar un patrón (corredor de prueba predeterminado de Django) con el indicador de opción --pattern="my_pattern_*.py".

Entonces, si está en su manage.pydirectorio y desea ejecutar la prueba test_adentro de la TestCasesubclase Adentro de un archivo tests.pybajo la aplicación / módulo example, haría:

python manage.py test example.tests.A.test_a

Si no desea incluir una dependencia y está en Django 1.6 o posterior, así es como lo hace.

Consulte la documentación de Django para obtener más información.

cristiano2lopes
fuente
Es bueno ver esta característica integrada en Django ahora.
hekevintran
No puedo hacer que esto funcione en absoluto: error: option --pattern not recognizedyinvalid command name
geoidesic
¡Esto funciona muy bien en Django v3!
Kirk
11

Estaba teniendo este problema yo mismo y encontré esta pregunta, en caso de que alguien más aparezca, esto fue lo que desenterré. DjangoTestSuiteRuner utiliza un método llamado build_test (etiqueta) que determina qué casos de prueba ejecutar en función de la etiqueta. Analizando este método, resulta que están haciendo un getattr () en el módulo "modelos" o "prueba". Esto significa que si devuelve una suite, el corredor de prueba no está buscando sus casos de prueba en esa suite, solo se ve en uno de esos módulos.

Una solución rápida es utilizar __init__.pypara importar sus pruebas directamente en lugar de definir un conjunto. Esto los hace parte del módulo "prueba" y así build_test (etiqueta) puede encontrarlos.

Para su ejemplo anterior, tests/__init__.pysimplemente debe contener:

from field_tests import *
from storage_tests import *

Esto no es muy elegante y, por supuesto, si está tratando de hacer algo más complicado con su suite, entonces esto no funcionará, pero lo sería para este caso.

Chris T
fuente
11

Esto debería funcionar-

python manage.py test my_app.tests.storage_tests
Swapnil Patel
fuente
3

Ponga este código en su __init__.py e importará todas las clases de prueba en el paquete y subpaquetes. Esto le permitirá ejecutar pruebas específicas sin importar manualmente cada archivo.

import pkgutil
import unittest

for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
    module = loader.find_module(module_name).load_module(module_name)
    for name in dir(module):
        obj = getattr(module, name)
        if isinstance(obj, type) and issubclass(obj, unittest.case.TestCase):
            exec ('%s = obj' % obj.__name__)

Del mismo modo, para su conjunto de pruebas simplemente puede usar:

def suite():   
    return unittest.TestLoader().discover("appname.tests", pattern="*.py")

Ahora todo lo que tiene que hacer para las nuevas pruebas es escribirlas y asegurarse de que estén en la carpeta de pruebas. ¡No más mantenimiento tedioso de las importaciones!

Bryce Drennan
fuente