Uruchamianie konkretnego przypadku testowego w Django, gdy Twoja aplikacja ma katalog testing

165

Dokumentacja Django ( http://docs.djangoproject.com/en/1.3/topics/testing/#running-tests ) mówi, że możesz uruchamiać indywidualne przypadki testowe, określając je:

$ ./manage.py test animals.AnimalTestCase

Zakłada się, że masz testy w pliku tests.py w swojej aplikacji Django. Jeśli to prawda, to polecenie działa zgodnie z oczekiwaniami.

Mam swoje testy aplikacji Django w katalogu testing:

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

tests/__init__.pyPlik ma pakietem funkcji ():

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)

Aby przeprowadzić testy, które wykonuję:

$ ./manage.py test my_app

Próba określenia indywidualnego przypadku testowego rodzi wyjątek:

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

Próbowałem zrobić to, co powiedział komunikat o wyjątku:

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

Jak określić indywidualny przypadek testowy, gdy moje testy znajdują się w wielu plikach?

hekevintran
źródło

Odpowiedzi:

156

Do kasy django-nose . Pozwala określić testy do uruchomienia, takie jak:

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

lub jak wskazano w komentarzach, użyj składni:

python manage.py test another.test.TestCase.test_method
Sam Dolan
źródło
Dzięki @sdolan. Napotkał ten sam problem, co hekevintran. Przełączono na django-nose i naprawiono ten problem, działa również znacznie lepiej niż domyślny tester Django.
LeeMobile
To uruchamia test, ale jak uruchomić całą TestCase?
jMyles,
5
@jMyles:another.test:TestCase
Sam Dolan
4
Uwaga ludzie tacy jak ja, którzy na ślepo wklejają ze Stackoverflow: To będzie błąd bez wspomnianej wtyczki, użyj składni opisanej w drugiej odpowiedzi (. Zamiast :), która działa w Django 1.6+.
Andy Smith
1
Odrzuciłem tę odpowiedź, ponieważ w rzeczywistości nie odpowiada ona na pytanie OP, czyli jak to zrobić w Django. Raczej po prostu sugeruje przejście na Nosetest
Josh Brown
175

Od Django 1.6 możesz uruchomić kompletny przypadek testowy lub pojedynczy test, używając pełnej notacji kropkowej dla elementu, który chcesz uruchomić.

Automatyczne wykrywanie testów znajdzie teraz testy w każdym pliku, który zaczyna się od testu w katalogu roboczym, więc odpowiadając na pytanie, będziesz musiał zmienić nazwy plików, ale możesz teraz zachować je w wybranym katalogu. Jeśli chcesz używać niestandardowych nazw plików, możesz określić wzorzec (domyślny program uruchamiający testy Django) z flagą opcji --pattern="my_pattern_*.py".

Więc jeśli jesteś w swoim manage.pykatalogu i chcesz uruchomić testtest_a w TestCasepodklasie Awewnątrz pliku tests.pyw aplikacji / module example, wykonaj:

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

Jeśli nie chcesz dołączać zależności i jesteś w Django 1.6 lub nowszym, tak to robisz.

Zobacz dokumentację Django, aby uzyskać więcej informacji

cristiano2lopes
źródło
Miło widzieć teraz tę funkcję wbudowaną w Django.
hekevintran
W ogóle nie mogę sprawić, żeby to zadziałało: error: option --pattern not recognizediinvalid command name
geoidesic
Działa to świetnie w Django v3!
Kirk
11

Sam miałem ten problem i znalazłem to pytanie, na wypadek gdyby pojawił się ktoś inny, oto co wykopałem. DjangoTestSuiteRuner używa metody o nazwie build_test (etykieta), która na podstawie etykiety określa, jakie przypadki testowe należy uruchomić. Przyglądając się tej metodzie, okazuje się, że wykonują one getattr () na module „models” lub „test”. Oznacza to, że jeśli zwrócisz pakiet, moduł uruchamiający testy nie będzie szukał przypadków testowych w tym pakiecie, tylko zajrzy do jednego z tych modułów.

Szybkim obejściem jest użycie __init__.py bezpośredniego importu testów zamiast definiowania zestawu. Dzięki temu stają się częścią modułu „test”, dzięki czemu build_test (etykieta) może je znaleźć.

Na przykład powyżej tests/__init__.pypowinien zawierać:

from field_tests import *
from storage_tests import *

Nie jest to zbyt eleganckie i oczywiście jeśli próbujesz zrobić coś bardziej skomplikowanego ze swoim pakietem, to nie zadziała, ale w tym przypadku tak by się stało.

Chris T.
źródło
11

To powinno działać-

python manage.py test my_app.tests.storage_tests
Swapnil Patel
źródło
3

Umieść ten kod w swoim __init__.py, a zaimportuje wszystkie klasy testowe w pakiecie i podpakietach. Umożliwi to uruchomienie określonych testów bez ręcznego importowania każdego pliku.

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

Podobnie, dla swojego zestawu testów możesz po prostu użyć:

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

Teraz wszystko, co musisz zrobić dla nowych testów, to napisać je i upewnić się, że znajdują się w folderze testy. Koniec z żmudną konserwacją importu!

Bryce Drennan
źródło