Czy istnieje prosty mechanizm zastępowania ustawień Django w teście jednostkowym? Mam menedżera na jednym z moich modeli, który zwraca określoną liczbę najnowszych obiektów. Liczba zwracanych obiektów jest zdefiniowana przez ustawienie NUM_LATEST.
Może to spowodować niepowodzenie moich testów, gdyby ktoś zmienił ustawienie. Jak mogę zmienić ustawienia, setUp()
a następnie przywrócić je tearDown()
? Jeśli to nie jest możliwe, czy jest jakiś sposób, w jaki mogę małpować poprawkę metody lub kpić z ustawień?
EDYCJA: Oto mój kod menedżera:
class LatestManager(models.Manager):
"""
Returns a specific number of the most recent public Articles as defined by
the NEWS_LATEST_MAX setting.
"""
def get_query_set(self):
num_latest = getattr(settings, 'NEWS_NUM_LATEST', 10)
return super(LatestManager, self).get_query_set().filter(is_public=True)[:num_latest]
Menedżer używa settings.NEWS_LATEST_MAX
do dzielenia zestawu zapytań. getattr()
Jest po prostu wykorzystane do zapewnienia domyślne ustawienie nie powinien istnieć.
django
settings
testing
django-managers
Soviut
źródło
źródło
Odpowiedzi:
EDYCJA: Ta odpowiedź ma zastosowanie, jeśli chcesz zmienić ustawienia dla niewielkiej liczby określonych testów.
Od wersji Django 1.4 istnieją sposoby na nadpisanie ustawień podczas testów: https://docs.djangoproject.com/en/dev/topics/testing/tools/#overriding-settings
TestCase będzie miał menedżera kontekstu self.settings, a także dekorator @override_settings, który można zastosować do metody testowej lub całej podklasy TestCase.
Te funkcje nie istniały jeszcze w Django 1.3.
Jeśli chcesz zmienić ustawienia dla wszystkich testów, zechcesz utworzyć osobny plik ustawień do testu, który będzie mógł ładować i zastępować ustawienia z głównego pliku ustawień. W innych odpowiedziach jest kilka dobrych podejść do tego zagadnienia; Widziałem udane odmiany zarówno podejścia hspandera, jak i dmitrii .
źródło
self.settings().wrapped.MEDIA_ROOT
, ale to dość okropne.@modify_settings(MIDDLEWARE_CLASSES=...
(dziękuję za tę odpowiedź)Możesz zrobić wszystko, co chcesz z
UnitTest
podklasą, w tym ustawiać i odczytywać właściwości instancji:Ponieważ przypadki testowe django działają jednowątkowo, jestem ciekaw, co jeszcze może modyfikować wartość NUM_LATEST? Jeśli to „coś innego” zostanie wywołane przez twoją procedurę testową, to nie jestem pewien, czy jakakolwiek ilość małpich poprawek zapisze test bez unieważnienia prawdziwości samych testów.
źródło
settings.TEMPLATE_LOADERS
... Więc to nie jest przynajmniej ogólny sposób, ustawienia lub Django nie są przeładowywane ani nic z tą sztuczką.Chociaż zastąpienie konfiguracji ustawień w czasie wykonywania może pomóc, moim zdaniem powinieneś utworzyć osobny plik do testowania. Oszczędza to dużo konfiguracji do testowania i zapewniłoby, że nigdy nie zrobisz czegoś nieodwracalnego (np. Wyczyszczenie pomostowej bazy danych).
Powiedz, że plik testowy istnieje w „my_project / test_settings.py”, dodaj
w twoim manage.py. Zapewni to, że po uruchomieniu
python manage.py test
będziesz używać tylko ustawień test_settings. Jeśli używasz innego klienta testowego, takiego jak pytest, możesz równie łatwo dodać to do pytest.iniźródło
Możesz przejść
--settings
opcję podczas uruchamiania testówźródło
Aktualizacja : poniższe rozwiązanie jest potrzebne tylko w Django 1.3.x i wcześniejszych. Dla> 1.4 zobacz odpowiedź slinkpa .
Jeśli często zmieniasz ustawienia w swoich testach i używasz Pythona ≥2,5, jest to również przydatne:
Następnie możesz:
źródło
yield
instrukcji, z ostatnią częścią funkcji zawartą wfinally
bloku, aby ustawienia były zawsze przywracane.@override_settings
jest świetny, jeśli nie ma wielu różnic między konfiguracjami środowiska produkcyjnego i testowego.W innym przypadku lepiej po prostu mieć inne pliki ustawień. W takim przypadku Twój projekt będzie wyglądał następująco:
Musisz więc mieć większość swoich ustawień w,
base.py
a następnie w innych plikach musisz zaimportować wszystko stamtąd i zastąpić niektóre opcje. Oto jaktest.py
będzie wyglądał Twój plik:Następnie albo musisz podać
--settings
opcję jak w odpowiedzi @MicroPyramid, lub określićDJANGO_SETTINGS_MODULE
zmienną środowiskową, a następnie możesz uruchomić testy:źródło
Znalazłem to podczas próby naprawienia niektórych dokumentów ... Dla kompletności chcę wspomnieć, że jeśli zamierzasz zmodyfikować ustawienia podczas korzystania z doctestów, powinieneś to zrobić przed zaimportowaniem czegokolwiek innego ...
źródło
O pytest użytkowników.
Największym problemem jest:
override_settings
nie działa z pytest.TestCase
sprawią, że to zadziała, ale nie możesz wtedy używać urządzeń pytest.Rozwiązaniem jest użycie
settings
udokumentowanego mocowania tutaj .Przykład
I na wypadek, gdybyś musiał zaktualizować wiele pól
źródło
Możesz zmienić ustawienie nawet dla pojedynczej funkcji testowej.
lub możesz nadpisać ustawienie dla każdej funkcji w klasie.
źródło
Używam pytest.
Udało mi się to rozwiązać w następujący sposób:
źródło
Możesz zastąpić ustawienia w teście w następujący sposób:
A jeśli potrzebujesz tych samych ustawień w innym pliku, możesz po prostu zaimportować je bezpośrednio
test_settings
.źródło
Jeśli masz wiele plików testowych umieszczonych w podkatalogu (pakiet Pythona), możesz nadpisać ustawienia dla wszystkich tych plików na podstawie warunku obecności ciągu „test” w sys.argv
__init__.py:
Nie jest to najlepsze podejście. Użyto go do zmiany brokera Selera z Redis na Memory.
źródło
Utworzyłem nowy plik settings_test.py, który importowałby wszystko z pliku settings.py i modyfikował wszystko, co było inne do celów testowych. W moim przypadku podczas testowania chciałem użyć innego zasobnika do przechowywania w chmurze.
settings_test.py:
manage.py:
źródło