Esecuzione di un caso di test specifico in Django quando l'app ha una directory di test


165

La documentazione di Django ( http://docs.djangoproject.com/en/1.3/topics/testing/#running-tests ) afferma che è possibile eseguire singoli casi di test specificandoli:

$ ./manage.py test animals.AnimalTestCase

Questo presuppone che tu abbia i tuoi test in un file tests.py nella tua applicazione Django. Se questo è vero, allora questo comando funziona come previsto.

Ho i miei test per un'applicazione Django in una directory di test:

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

Il tests/__init__.pyfile ha una funzione 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)

Per eseguire i test che faccio:

$ ./manage.py test my_app

Il tentativo di specificare un singolo test case solleva un'eccezione:

$ ./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

Ho provato a fare ciò che diceva il messaggio di eccezione:

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

Come posso specificare un singolo test case quando i miei test sono in più file?

Risposte:


156

Acquista django-nose . Ti consente di specificare i test da eseguire come:

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

o come notato nei commenti, utilizzare la sintassi:

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

Grazie @sdolan. Si è verificato lo stesso problema di hekevintran. Passato a django-nose e risolto quel problema, funziona anche molto meglio del test runner di Django predefinito.
LeeMobile,

Questo esegue un test, ma come eseguire un intero TestCase?
jMyles l'

5
@jMyles:another.test:TestCase
Sam Dolan,

4
Attenzione gente come me che incolla ciecamente da StackOverflow: questo errore senza il plugin menzionato, usa la sintassi descritta nell'altra risposta (. Anziché :) che funziona in Django 1.6+.
Andy Smith,

1
ho votato in negativo questa risposta perché in realtà non risponde alla domanda del PO, che era come farlo in Django. Piuttosto, suggerisce solo di passare a Nosetest
Josh Brown il

175

Da Django 1.6 è possibile eseguire un caso di test completo o un singolo test, utilizzando la notazione punto completa per l'elemento che si desidera eseguire.

Il rilevamento automatico dei test ora troverà i test in qualsiasi file che inizia con test nella directory di lavoro, quindi rispondendo alla domanda dovresti rinominare i tuoi file, ma ora puoi tenerli all'interno della directory che desideri. Se si desidera utilizzare nomi di file personalizzati, è possibile specificare un modello (runner di test Django predefinito) con l'opzione flag --pattern="my_pattern_*.py".

Quindi, se ti trovi nella tua manage.pydirectory e desideri eseguire il test test_aall'interno della TestCasesottoclasse Aall'interno di un file tests.pysotto l'app / il modulo, exampledovresti:

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

Se non vuoi includere una dipendenza e sei in Django 1.6 o successivo, è così che lo fai.

Consulta la documentazione di Django per ulteriori informazioni


È bello vedere questa funzionalità integrata in Django ora.
Hekevintran,

Non riesco a far funzionare tutto questo: error: option --pattern not recognizedeinvalid command name
geoidesic il

Funziona alla grande in Django v3!
Kirk,

11

Stavo avendo questo problema da solo e ho trovato questa domanda, nel caso in cui arrivasse qualcun altro, ecco cosa ho scavato. DjangoTestSuiteRuner utilizza un metodo chiamato build_test (etichetta) che determina quali casi di test eseguire sulla base dell'etichetta. Osservando questo metodo si scopre che stanno facendo un getattr () sul modulo "modelli" o "test". Ciò significa che se si restituisce una suite, il test runner non sta cercando i casi di test in quella suite, ma cerca solo in uno di quei moduli.

Una soluzione rapida è utilizzare __init__.pyper importare direttamente i test invece di definire una suite. Li rende parte del modulo "test" e quindi build_test (etichetta) li trova.

Per il tuo esempio sopra, tests/__init__.pydovrebbe semplicemente contenere:

from field_tests import *
from storage_tests import *

Questo non è molto elegante e ovviamente se stai cercando di fare qualcosa di più complicato con la tua suite, allora non funzionerà, ma sarebbe per questo caso.


11

Questo dovrebbe funzionare-

python manage.py test my_app.tests.storage_tests


3

Inserisci questo codice nel tuo __init__.py e importerà tutte le classi di test nel pacchetto e nei pacchetti secondari. Ciò ti consentirà di eseguire test specifici senza importare manualmente ogni file.

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__)

Allo stesso modo, per la tua suite di test puoi semplicemente usare:

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

Ora tutto ciò che devi fare per i nuovi test è scriverli e assicurarti che siano nella cartella dei test. Niente più noioso mantenimento delle importazioni!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.