Moje testy jednostkowe Django trwają długo, więc szukam sposobów, aby to przyspieszyć. Rozważam zainstalowanie dysku SSD , ale wiem, że ma to też swoje wady. Oczywiście są rzeczy, które mógłbym zrobić z moim kodem, ale szukam poprawki strukturalnej. Nawet wykonanie pojedynczego testu jest powolne, ponieważ za każdym razem należy odbudować bazę danych / migrować na południe. Oto mój pomysł ...
Ponieważ wiem, że testowa baza danych zawsze będzie dość mała, dlaczego nie mogę po prostu skonfigurować systemu tak, aby zawsze przechowywać całą testową bazę danych w pamięci RAM? Nigdy nie dotykaj dysku. Jak to skonfigurować w Django? Wolałbym nadal używać MySQL, ponieważ tego właśnie używam w produkcji, ale jeśli SQLite 3 lub coś innego ułatwi to, pójdę w ten sposób.
Czy SQLite lub MySQL mają opcję uruchamiania w całości w pamięci? Powinno być możliwe skonfigurowanie dysku RAM, a następnie skonfigurowanie testowej bazy danych tak, aby przechowywała tam swoje dane, ale nie jestem pewien, jak powiedzieć Django / MySQL, aby używał innego katalogu danych dla określonej bazy danych, zwłaszcza że jest ona ciągle wymazywana i odtwarzałem każdy bieg. (Jestem na komputerze Mac FWIW.)
źródło
"test" in sys.argv
; może się uruchomić, gdy tego nie chcesz, npmanage.py collectstatic -i test
.sys.argv[1] == "test"
jest dokładniejszym warunkiem, który nie powinien mieć tego problemu.Zwykle tworzę osobny plik ustawień do testów i używam go w poleceniu testowym np
Ma dwie zalety:
Nie musisz sprawdzać,
test
czy takie magiczne słowo w sys.argvtest_settings.py
może po prostu byćLub możesz dodatkowo dostosować go do swoich potrzeb, wyraźnie oddzielając ustawienia testowe od ustawień produkcyjnych.
Kolejną korzyścią jest to, że możesz uruchomić test z produkcyjnym silnikiem bazy danych zamiast sqlite3, unikając subtelnych błędów, więc podczas programowania
a przed zatwierdzeniem kodu uruchom raz
tylko po to, aby mieć pewność, że wszystkie testy naprawdę zdały.
źródło
MySQL obsługuje mechanizm magazynowania o nazwie „MEMORY”, który można skonfigurować w konfiguracji bazy danych (
settings.py
) jako taki:Pamiętaj, że silnik magazynu MEMORY nie obsługuje kolumn blob / text, więc jeśli używasz
django.db.models.TextField
tego, nie zadziała.źródło
Nie mogę odpowiedzieć na twoje główne pytanie, ale jest kilka rzeczy, które możesz zrobić, aby przyspieszyć działanie.
Po pierwsze, upewnij się, że Twoja baza danych MySQL jest skonfigurowana do korzystania z InnoDB. Następnie może użyć transakcji do przywrócenia stanu bazy danych przed każdym testem, co z mojego doświadczenia doprowadziło do ogromnego przyspieszenia. Możesz przekazać polecenie init bazy danych w swoim pliku settings.py (składnia Django 1.2):
Po drugie, nie musisz za każdym razem uruchamiać migracji na południe. Ustaw
SOUTH_TESTS_MIGRATE = False
w swoim settings.py, a baza danych zostanie utworzona przy użyciu zwykłej syncdb, co będzie znacznie szybsze niż wykonanie wszystkich historycznych migracji.źródło
369 tests in 498.704s
do369 tests in 41.334s
. To ponad 10 razy szybciej!--keep
do utrwalenia bazy danych i nie wymagać ponownego stosowania całego zestawu migracji przy każdym uruchomieniu testowym. Nowe migracje będą nadal działać. Jeśli często przełączasz się między gałęziami, łatwo jest jednak uzyskać niespójny stan (możesz cofnąć nowe migracje przed przełączeniem, zmieniając bazę danych na testową i uruchamiającmigrate
, ale jest to trochę uciążliwe).Możesz wykonać podwójne ulepszenia:
Używam obu sztuczek i jestem całkiem zadowolony.
Jak skonfigurować go dla MySQL na Ubuntu:
Uwaga, to tylko do testów, po ponownym uruchomieniu baza danych z pamięci zostaje utracona!
źródło
Inne podejście: uruchom inną instancję MySQL w tempfs, która używa dysku RAM. Instrukcje w tym wpisie na blogu: Przyspieszenie MySQL do testowania w Django .
Zalety:
źródło
Rozszerzając odpowiedź Anuraga, uprościłem proces, tworząc te same ustawienia test_settings i dodając następujące do manage.py
wydaje się czystszy, ponieważ sys jest już zaimportowany, a manage.py jest używany tylko z wiersza poleceń, więc nie ma potrzeby zaśmiecania ustawień
źródło
"test" in sys.argv
; może się uruchomić, gdy tego nie chcesz, npmanage.py collectstatic -i test
.sys.argv[1] == "test"
jest dokładniejszym warunkiem, który nie powinien mieć tego problemu../manage.py
bez argumentów (np. aby zobaczyć, które wtyczki są dostępne, tak samo jak--help
)len(sys.argv) > 1 and sys.argv[1] == "test"
Użyj poniżej w swoim
setting.py
źródło