Bardzo częstą strukturą katalogów nawet prostego modułu Pythona wydaje się być rozdzielenie testów jednostkowych na ich własny test
katalog:
new_project/
antigravity/
antigravity.py
test/
test_antigravity.py
setup.py
etc.
na przykład zobacz howto projektu Python .
Moje pytanie brzmi: Jaki jest typowy sposób przeprowadzania testów? Podejrzewam, że jest to oczywiste dla wszystkich oprócz mnie, ale nie można po prostu uruchomić python test_antigravity.py
z katalogu testowego, ponieważ import antigravity
zawiedzie, ponieważ moduł nie znajduje się na ścieżce.
Wiem, że mógłbym modyfikować PYTHONPATH i inne sztuczki związane ze ścieżką wyszukiwania, ale nie mogę uwierzyć, że to najprostszy sposób - to dobrze, jeśli jesteś programistą, ale nie realistycznie oczekujesz, że użytkownicy będą używać, jeśli chcą tylko sprawdzić testy przechodzący.
Inną alternatywą jest po prostu skopiowanie pliku testowego do innego katalogu, ale wydaje się nieco głupi i nie ma sensu umieszczania go w osobnym katalogu na początek.
Więc jeśli właśnie pobrałeś źródło do mojego nowego projektu, jak byś przeprowadził testy jednostkowe? Wolę odpowiedź, która pozwoli mi powiedzieć użytkownikom: „Aby uruchomić testy jednostkowe, wykonaj X”.
źródło
unittest
interfejsu wiersza poleceń, jak opisano w mojej odpowiedzi poniżej, więc nie musisz dodawać katalogu do ścieżki.Odpowiedzi:
Moim zdaniem najlepszym rozwiązaniem jest skorzystanie z
unittest
interfejsu wiersza poleceń, który doda katalog do katalogu,sys.path
więc nie musisz (zrobione wTestLoader
klasie).Na przykład dla takiej struktury katalogów:
Możesz po prostu uruchomić:
W przypadku struktury katalogów takiej jak Twoja:
A w modułach testowych w
test
pakiecie możeszantigravity
jak zwykle zaimportować pakiet i jego moduły:Uruchamianie jednego modułu testowego:
Aby uruchomić pojedynczy moduł testowy, w tym przypadku
test_antigravity.py
:Po prostu odwołaj się do modułu testowego w taki sam sposób, jak go importujesz.
Uruchamianie pojedynczego przypadku testowego lub metody testowej:
Możesz także uruchomić jedną
TestCase
lub jedną metodę testową:Uruchamianie wszystkich testów:
Możesz także użyć funkcji wykrywania testów, która wykryje i uruchomi wszystkie testy, muszą to być moduły lub pakiety o nazwie
test*.py
(można je zmienić za pomocą-p, --pattern
flagi):Spowoduje to uruchomienie wszystkich
test*.py
modułów wtest
pakiecie.źródło
python -m unittest discover
znajdzie i uruchomi testy wtest
katalogu, jeśli są one nazwanetest*.py
. Jeśli nazwałeś podkatalogtests
, użyjpython -m unittest discover -s tests
, a jeśli nazwałeś pliki testoweantigravity_test.py
, użyjpython -m unittest discover -s tests -p '*test.py'
Nazwy plików mogą używać podkreślników, ale nie myślników.ImportError: No module named 'test.test_antigravity'
powodu konfliktu z podmodułem testowym najbardziej niepublicznej biblioteki. Może ekspert może potwierdzić i zmienić nazwę podkatalogu odpowiedzi na np. „Testy” (liczba mnoga).test_antigravity.py
nadal zgłasza błąd importu zarównoimport antigravity
ifrom antigravity import antigravity
, jak dobrze. Mam oba__init_.py
pliki i dzwoniępython3 -m unittest discover
znew project
katalogu. Co jeszcze może być nie tak?test/__init__.py
ma tutaj kluczowe znaczenie, nawet jeśli jest pustytest
jest wyjątkowa ... ale dla przypomnienia , nie jest. : Ppython -m unittest discover
działatests/
równie dobrze z plikami testowymitest/
.Najprostszym rozwiązaniem dla użytkowników jest zapewnienie skryptu wykonywalnego (
runtests.py
lub niektórych takich), który uruchamia niezbędne środowisko testowe, w tym, w razie potrzeby,sys.path
tymczasowo dodaje katalog główny projektu . Nie wymaga to od użytkowników ustawiania zmiennych środowiskowych, coś takiego działa dobrze w skrypcie bootstrap:Następnie instrukcje dla użytkowników mogą być tak proste, jak „
python runtests.py
”.Oczywiście, jeśli naprawdę potrzebna jest ścieżka
os.path.dirname(__file__)
, to wcale nie musisz jej dodawaćsys.path
; Python zawsze umieszcza katalog aktualnie uruchomionego skryptu na początkusys.path
, więc w zależności od struktury katalogów, wystarczy zlokalizować goruntests.py
we właściwym miejscu.Ponadto, najbardziej niezawodny moduł w Pythonie 2.7+ (który jest backportowany jako unittest2 dla Python 2.6 i wcześniejszych) ma teraz wbudowane wykrywanie testowe , więc nos nie jest już potrzebny, jeśli chcesz automatycznego wykrywania testu: instrukcje użytkownika mogą być tak proste, jak
python -m unittest discover
.źródło
python -m pdb tests\test_antigravity.py
. Wewnątrz pdb wykonałem,sys.path.insert(0, "antigravity")
co pozwoliło na rozwiązanie instrukcji importu tak, jakby działał moduł.Generalnie tworzę skrypt „uruchom testy” w katalogu projektu (ten, który jest wspólny zarówno dla katalogu źródłowego, jak i
test
), który ładuje mój pakiet „Wszystkie testy”. Jest to zwykle kod typu „kocioł”, więc mogę go ponownie wykorzystać od projektu do projektu.run_tests.py:
test / all_tests.py (z Jak uruchomić wszystkie testy jednostkowe Pythona w katalogu? )
Dzięki tej konfiguracji możesz rzeczywiście tylko
include antigravity
w swoich modułach testowych. Minusem jest to, że potrzebujesz więcej kodu pomocniczego do wykonania konkretnego testu ... Po prostu uruchamiam je za każdym razem.źródło
run tests
skrypt w katalogu projektu i okazało się dużo bardziej przejrzysty sposób to zrobić. Wysoce polecany.Z artykułu, do którego linkowałeś:
Być może powinieneś spojrzeć na nos, jak to sugeruje?
źródło
Miałem ten sam problem z osobnym folderem testów jednostkowych. Spośród wymienionych propozycji mogę dodać ścieżkę źródłową absolutną do
sys.path
.Zaletą następującego rozwiązania jest to, że można uruchomić plik
test/test_yourmodule.py
bez uprzedniej zmiany w katalog testowy:źródło
jeśli uruchomisz „python setup.py develop”, pakiet znajdzie się na ścieżce. Ale możesz tego nie chcieć, ponieważ możesz zainfekować systemową instalację Pythona, dlatego istnieją narzędzia takie jak virtualenv i buildout .
źródło
Rozwiązanie / przykład dla Unittest modułu Python
Biorąc pod uwagę następującą strukturę projektu:
Możesz uruchomić swój projekt z katalogu głównego za pomocą
python project_name
, który wywołujeProjectName/project_name/__main__.py
.Aby uruchomić testy
python test
, działając skutecznieProjectName/test/__main__.py
, musisz wykonać następujące czynności:1) Zamień
test/models
katalog w pakiet, dodając__init__.py
plik. Dzięki temu przypadki testowe w podkatalogu są dostępne ztest
katalogu nadrzędnego .2) Zmodyfikuj ścieżkę systemową,
test/__main__.py
aby uwzględnićproject_name
katalog.Teraz możesz pomyślnie importować elementy z
project_name
testów.źródło
Użyj,
setup.py develop
aby katalog roboczy stał się częścią zainstalowanego środowiska Python, a następnie uruchom testy.źródło
invalid command 'develop'
i ta opcja nie jest wymieniona, jeśli o to poproszęsetup.py --help-commands
. Czy coś musi byćsetup.py
samo w sobie, aby to zadziałało?import setuptools
misetup.py
pliku. Ale wydaje mi się, że to pokazuje, że nie będzie to działało cały czas dla modułów innych osób.pip install -e .
To również dodaje pakiet do środowiska Python bez kopiowania źródła, umożliwiając kontynuowanie edycji w miejscu, w którym się znajduje.pip install -e .
jest dokładnie tak samo, jakpython setup.py develop
, po prostu małpuje się,setup.py
aby używać setuptools, nawet jeśli tak naprawdę nie działa, więc działa tak czy inaczej.Jeśli używasz kodu VS, a testy znajdują się na tym samym poziomie co projekt, to uruchomienie i debugowanie kodu nie działa od razu po wyjęciu z pudełka. Co możesz zrobić, to zmienić plik launch.json:
Kluczową linią jest tutaj envFile
W katalogu głównym projektu dodaj plik .env
Wewnątrz pliku .env dodaj ścieżkę do katalogu głównego projektu. Spowoduje to tymczasowe dodanie
ścieżkę do swojego projektu, a będziesz mógł korzystać z testów jednostkowych debugowania z VS Code
źródło
Zauważyłem, że jeśli uruchomisz najdelikatniejszy interfejs wiersza poleceń z katalogu „src”, to importowanie działa poprawnie bez modyfikacji.
Jeśli chcesz umieścić to w pliku wsadowym w katalogu projektu, możesz to zrobić:
źródło
Długo miałem ten sam problem. Ostatnio wybrałem następującą strukturę katalogów:
a w
__init__.py
skrypcie folderu testowego piszę:Bardzo ważny dla współdzielenia projektu jest Makefile, ponieważ wymusza prawidłowe uruchamianie skryptów. Oto polecenie, które umieściłem w Makefile:
Plik Makefile jest ważny nie tylko ze względu na uruchamiane polecenie, ale także ze względu na to, skąd go uruchamia . Jeśli wykonasz cd w testach i zrobisz
python -m unittest discover .
, to nie zadziała, ponieważ skrypt init w module unit_tests wywołuje os.getcwd (), co wskazywałoby następnie na niepoprawną ścieżkę bezwzględną (która byłaby dołączona do sys.path i byłby brakujący folder źródłowy). Skrypty byłyby uruchamiane, ponieważ funkcja Discover znajduje wszystkie testy, ale nie działałyby poprawnie. Tak więc plik Makefile ma na celu uniknięcie konieczności pamiętania tego problemu.Bardzo podoba mi się to podejście, ponieważ nie muszę dotykać folderu src, testów jednostkowych ani zmiennych środowiskowych i wszystko działa płynnie.
Daj mi znać, jeśli wam się spodoba.
Mam nadzieję, że to pomaga
źródło
Oto struktura mojego projektu:
Uważam, że lepiej jest zaimportować w metodzie setUp ():
źródło
Używam Python 3.6.2
Aby zainstalować pytest :
sudo pip install pytest
Nie ustawiłem żadnej zmiennej ścieżki i mój import nie kończy się niepowodzeniem z tą samą „projektową” strukturą projektu.
Skomentowałem te rzeczy:
if __name__ == '__main__'
tak:test_antigravity.py
źródło
Możliwe jest użycie otoki, która uruchamia wybrane lub wszystkie testy.
Na przykład:
lub aby uruchomić wszystkie testy rekursywnie, użyj globbing (
tests/**/*.py
) (enable byshopt -s globstar
).Opakowanie może zasadniczo służyć
argparse
do analizowania argumentów takich jak:Następnie załaduj wszystkie testy:
następnie dodaj je do swojego zestawu testów (używając
inspect
):i uruchom je:
Sprawdź ten przykład, aby uzyskać więcej informacji.
Zobacz także: Jak uruchomić wszystkie testy jednostkowe Pythona w katalogu?
źródło
Python 3+
Dodawanie do @Pierre
Przy użyciu
unittest
takiej struktury katalogów:Aby uruchomić moduł testowy
test_antigravity.py
:Lub singiel
TestCase
Obowiązkowe nie zapomnij
__init__.py
nawet jeśli pusty, inaczej nie będzie działać.źródło
Nie możesz importować z katalogu nadrzędnego bez jakiegoś voodoo. Oto jeszcze jeden sposób, który działa przynajmniej z Pythonem 3.6.
Najpierw przygotuj plik test / context.py z następującą zawartością:
Następnie wykonaj następujący import w pliku test / test_antigravity.py:
Zauważ, że powodem tej klauzuli try-wyjątkiem jest to
Dzięki tej sztuczce oboje działają.
Teraz możesz uruchomić wszystkie pliki testowe w katalogu testowym za pomocą:
lub uruchom pojedynczy plik testowy z:
Ok, nie jest to o wiele ładniejsza niż zawartość content.py w ramach test_antigravity.py, ale może trochę. Sugestie są mile widziane.
źródło
Jeśli masz wiele katalogów w katalogu testowym, musisz dodać do każdego katalogu
__init__.py
plik.Następnie, aby uruchomić każdy test na raz, uruchom:
Źródło:
python -m unittest -h
źródło
Ten skrypt BASH wykona najbardziej testowy katalog Pythona z dowolnego miejsca w systemie plików, bez względu na katalog roboczy, w którym się znajdujesz.
Jest to przydatne, gdy pozostajesz w katalogu roboczym
./src
lub./example
roboczym i potrzebujesz szybkiego testu jednostkowego:Nie ma potrzeby, aby
test/__init__.py
plik obciążał pakiet / obciążenie pamięci podczas produkcji.źródło
W ten sposób możesz uruchamiać skrypty testowe z dowolnego miejsca bez konieczności zmieniania zmiennych systemowych z wiersza poleceń.
Dodaje to główny folder projektu do ścieżki pythona, z lokalizacją znalezioną względem samego skryptu, a nie względem bieżącego katalogu roboczego.
Dodaj to na początku wszystkich skryptów testowych. Spowoduje to dodanie głównego folderu projektu do ścieżki systemowej, dzięki czemu będzie działał każdy importowany z niego moduł. I nie ma znaczenia, skąd uruchamiasz testy.
Możesz oczywiście zmienić plik ścieżka_projektu, aby dopasować położenie głównego folderu projektu.
źródło
Jeśli szukasz rozwiązania tylko z wiersza poleceń:
W oparciu o następującą strukturę katalogów (uogólniony z dedykowanym katalogiem źródłowym):
Windows : (w
new_project
)Zobacz to pytanie, jeśli chcesz użyć tego we wsadowej pętli for.
Linux : (w
new_project
)Dzięki takiemu podejściu można również dodać więcej katalogów do PYTHONPATH, jeśli to konieczne.
źródło
Naprawdę powinieneś użyć narzędzia pip.
Służy
pip install -e .
do instalowania pakietu w trybie programowania. Jest to bardzo dobra praktyka, zalecana przez pytest (patrz dokumentacja dobrych praktyk , gdzie można również znaleźć dwa układy projektów do naśladowania).źródło
pytest
lepiej jest uruchamiać testy, ponieważ dane wyjściowe konsoli są wyświetlane w kolorze, z informacjami o stosie i szczegółowymi informacjami o błędzie potwierdzenia.