2010-07-30 5 views
13

Ho alcuni metodi scritti in un oggetto django.test.TestCase che vorrei eseguire da manage.py shell sul mio vero database. Ma quando cerco di istanziare l'oggetto TestCase per eseguire il metodo di prova, ottengo questo errore:Come si esegue un django TestCase manualmente/contro un altro database?

ValueError: no such test method in <class 'track.tests.MentionTests'>: runTest 

C'è un modo per istanziare gli oggetti TestCase? O c'è un modo per eseguire un metodo di test su un database non di test?

risposta

1

Dal Django testing docs:

Running tests

Once you've written tests, run them using the test subcommand of your project's manage.py utility:

$ ./manage.py test

By default, this will run every test in every application in INSTALLED_APPS. If you only want to run tests for a particular application, add the application name to the command line. For example, if your INSTALLED_APPS contains 'myproject.polls' and 'myproject.animals', you can run the myproject.animals unit tests alone with this command:

$ ./manage.py test animals

Note that we used animals, not myproject.animals. New in Django 1.0: You can now choose which test to run.

You can be even more specific by naming an individual test case. To run a single test case in an application (for example, the AnimalTestCase described in the "Writing unit tests" section), add the name of the test case to the label on the command line:

$ ./manage.py test animals.AnimalTestCase

And it gets even more granular than that! To run a single test method inside a test case, add the name of the test method to the label:

$ ./manage.py test animals.AnimalTestCase.testFluffyAnimals

L'ultimo esempio dovrebbe essere applicabile nel vostro caso.

Se questo è ciò che stai facendo, dovrai inserire una descrizione più dettagliata del codice utilizzato nel tuo caso di test.

+0

Certo, ma questo crea un nuovo database di test da eseguire contro. Come posso eseguirlo sul database principale (non test)? – Leopd

11

Ecco un metodo che ho trovato di recente. Non ho ancora trovato niente di meglio.

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 

Secondo la documentazione, dovremmo chiamare setup_test_environment() quando si esegue manualmente test. django.test utilizza unittest per il test in modo da poter utilizzare TestResult da unittest per acquisire risultati durante l'esecuzione del test.

In Django 1.2, DjangoTestRunner potrebbe essere utilizzato per test più strutturati. Non ho ancora provato questo.

+1

Quando faccio questo il mio TestCase non può accedere a self.client. Inoltre è possibile eseguire tutte le funzioni di test all'interno di TestCase senza dover giocare con getattr ecc.? – pielgrzym

+1

quello che voglio veramente è eseguire il test case in pdb. – mcr

+0

È fantastico, grazie! –

1

mi sono imbattuto in questo, e elaborato la seguente soluzione:

Nel vostro frontend/tests.py, impostare le cose in questo modo:

# 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(), .. ]) 

si esegue questo test con

~$ unit2 myapp.tests.runNonDjangoTests 

Per ulteriori informazioni, vedere http://pypi.python.org/pypi/unittest2

Ciò consente anche di eseguire test unitari sul database principale, con tutti gli effetti collaterali potenzialmente distruttivi. Nota che unit2 è piuttosto pericoloso in questo contesto, se chiami unit2 myapp.tests eseguirà tutti i tuoi normali test di Django senza metterli in un database di test.

2

Il problema "runTest" di solito viene fuori dal momento che le persone trascurano il fatto che l'unittest.TestCase ha un argomento predefinito nel suo costruttore. Date un'occhiata al lib/python/unittest/case.py

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

Si noti che la baseclass "TestCase" non fornisce un'implementazione di default di "def runTest", ma lo fa nethertheless cercare di invocarlo. Ecco da dove viene l'errore. La vera confusione deriva dal fatto che l'utilizzo di "unittest.main()" non ha bisogno di un metodo runTest ma chiamerà comunque tutte le funzioni "def test *". Funziona ... ma non a causa di un comportamento predefinito di TestCase ma del codice di ispezione da non selezionato.principale - questo sta facendo qualcosa di simile a quanto segue:

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) 

Rispondere alla domanda iniziale "Ho alcuni metodi scritti in un django.test.TestCase": è necessario aggiungere ogni metodo singolarmente su una suite di test utilizzando il TestClass e fornendo il nome del metodo di destinazione come primo argomento sulla creazione dell'oggetto.

Problemi correlati