¿Cómo ejecuto un django TestCase manualmente / contra otra base de datos?

Tengo algunos métodos escritos en un objeto django.test.TestCase que me gustaría ejecutar desde el manage.py shell en mi base de datos real. Pero cuando bash crear una instancia del objeto TestCase para ejecutar el método de prueba, aparece este error:

 ValueError: no such test method in : runTest 

¿Hay una manera de crear una instancia de los objetos TestCase ? ¿O hay una manera de ejecutar un método de prueba contra una base de datos que no sea de prueba?

Aquí hay un método que encontré recientemente. Todavía no he encontrado nada mejor.

 from django.test.utils import setup_test_environment from unittest import TestResult from my_app.tests import TheTestWeWantToRun setup_test_environment() t = TheTestWeWantToRun('test_function_we_want_to_run') r = TestResult() t.run(r) r.testsRun # prints the number of tests that were run (should be 1) r.errors + r.failures # prints a list of the errors and failures 

De acuerdo con los documentos, deberíamos llamar a setup_test_environment() cuando setup_test_environment() pruebas manualmente. django.test utiliza unittest para realizar pruebas, por lo que podemos usar un TestResult de unittest para capturar los resultados al ejecutar la prueba.

En Django 1.2, DjangoTestRunner podría usarse para pruebas más estructuradas. Aunque no he intentado esto todavía.

El problema “runTest” generalmente surge cuando las personas pasan por alto el hecho de que unittest.TestCase tiene un argumento predeterminado en su constructor. Echa un vistazo a lib / python / unittest / case.py

 class TestCase: def __init__(self, methodName='runTest'): 

Tenga en cuenta que la clase de base “TestCase” no proporciona una implementación predeterminada de “def runTest”, pero no intenta invocarla. De ahí viene el error. La confusión real proviene del hecho de que el uso de “unittest.main ()” no necesita un método runTest pero aún así llamará a todas las funciones “def test *”. Esto funciona … pero no debido a un comportamiento predeterminado de TestCase sino al código de inspección de unittest.main; se trata de algo como lo siguiente:

 class MyTest(unittest.TestCase): def test_001(self): print "ok" if __name__ == "__main__": suite = unittest.TestSuite() for method in dir(MyTest): if method.startswith("test"): suite.addTest(MyTest(method)) unittest.TextTestRunner().run(suite) 

Respondiendo a la pregunta original “Tengo algunos métodos escritos en un django.test.TestCase”: debe agregar cada método individualmente en un testuite utilizando su clase de prueba y proporcionando el nombre del método objective como el primer argumento sobre la creación del objeto.

De los documentos de prueba de Django :

Pruebas de carrera

Una vez que haya escrito las pruebas, ejecútelas utilizando el subcomando de prueba de la utilidad manage.py de su proyecto:

$ ./manage.py prueba

De forma predeterminada, esto ejecutará todas las pruebas en cada aplicación en INSTALLED_APPS. Si solo desea ejecutar pruebas para una aplicación en particular, agregue el nombre de la aplicación a la línea de comandos. Por ejemplo, si su INSTALLED_APPS contiene ‘myproject.polls’ y ‘myproject.animals’, puede ejecutar las pruebas de la unidad myproject.animals solo con este comando:

$ ./manage.py prueba animales

Tenga en cuenta que utilizamos animales, no myproject.animals. Nuevo en Django 1.0: Ahora puedes elegir qué prueba ejecutar.

Puede ser aún más específico al nombrar un caso de prueba individual. Para ejecutar un solo caso de prueba en una aplicación (por ejemplo, el AnimalTestCase descrito en la sección “Pruebas de unidades de escritura”), agregue el nombre del caso de prueba a la etiqueta en la línea de comando:

$ ./manage.py prueba animales.AnimalTestCase

¡Y se vuelve aún más granular que eso! Para ejecutar un solo método de prueba dentro de un caso de prueba, agregue el nombre del método de prueba a la etiqueta:

$ ./manage.py prueba animales.AnimalTestCase.testFluffyAnimals

El último ejemplo debería ser aplicable en su caso.

Si esto es lo que está haciendo, deberá publicar una descripción más detallada del código empleado en su caso de prueba.

Me encontré con esto, y resolví la siguiente solución:

En tu myapp / tests.py , configura las cosas de esta manera:

 # get the straight-up Python unittest without the Django machinery # NOTE: this is unittest2, a backport of unit testing features from Python 2.7 # (running 2.6 at the time of writing) from django.utils import unittest # get the Django wraps from django.test import TestCase as DjangoTestCase # [..] # your normal Django unit tests, inheriting from DjangoTestCase # [..] class MyTest( unittest.TestCase ): def runTest( self ): # NOTE: required name self.failUnless( True is True ) def runNonDjangoTests(): return MyTest() # or unittest.TestSuite( [ MyTest(), .. ] ) 

Usted ejecuta esta prueba con

 ~$ unit2 myapp.tests.runNonDjangoTests 

Para obtener más información, consulte http://pypi.python.org/pypi/unittest2

Esto también le permite ejecutar pruebas unitarias en la base de datos principal, con todos los efectos secundarios potencialmente destructivos. Tenga en cuenta que unit2 es bastante peligroso en este contexto, si llama unit2 myapp.tests ejecutará todas sus pruebas normales de Django sin colocarlas en una base de datos de prueba.