Python - doctest vs. unittest [zamknięty]

160

Próbuję zacząć testowanie jednostkowe w Pythonie i zastanawiałem się, czy ktoś mógłby wyjaśnić zalety i wady doctest i unittest.

Do jakich warunków użyłbyś każdego z nich?

Sean
źródło

Odpowiedzi:

177

Obie są cenne. Używam zarówno doctest, jak i nosa, które zastępują unittest. Używam doctest w przypadkach, gdy test podaje przykład użycia, który jest faktycznie przydatny jako dokumentacja. Generalnie nie tworzę tych testów wyczerpujących, mając na celu wyłącznie informacyjne. Skutecznie używam doctest w odwrotnej kolejności: nie testowanie mojego kodu jest poprawne na podstawie mojego doctest, ale sprawdzenie, czy moja dokumentacja jest poprawna na podstawie kodu.

Powodem jest to, że uważam, że kompleksowe testy dokumentacyjne zaśmiecają twoją dokumentację, więc albo skończysz z bezużytecznymi dokumentami, albo niekompletnymi testami.

Aby faktycznie przetestować kod , celem jest dokładne przetestowanie każdego przypadku, a nie zilustrowanie tego, co robi na przykładzie, co jest innym celem, który moim zdaniem jest lepiej osiągnięty przez inne frameworki.

Brian
źródło
29
Jest o wiele mniej schematów, a testy są znacznie prostsze do napisania (i odczytania). Niski koszt rozpoczęcia pisania testów (tj. Po prostu napisz funkcję "test_foo ()" i gotowe) również pomaga zwalczyć pokusę robienia interesujących fragmentów kodu przed przybiciem testów.
Brian,
6
Myślę, że to fantastyczna odpowiedź.
James Brady
Z jakich innych frameworków testowych korzystasz? Czy jest to wyłącznie nos?
Joe,
6
Biorąc pod uwagę wiek tej odpowiedzi, prawdopodobnie warto wspomnieć, że większość „schematu” starszych wersji unittest w dużej mierze zniknęła. Wciąż bardziej lubię Nos, ale to raczej rzut do góry.
Adam Parkin
1
FYI Nos znajdował się w „trybie konserwacji” przez ostatnie kilka lat i prawdopodobnie zaprzestanie wszelkich prac rozwojowych (bez interwencji strony trzeciej). Jego opiekunowie zalecają nowym projektom użycie alternatywy.
Szósty
48

Unittest używam prawie wyłącznie.

Od czasu do czasu umieszczam coś w dokumentacji, której można użyć w doctest.

95% przypadków testowych jest nieczytelnych.

Czemu? Lubię skracać dokumentację i bardziej na temat. Czasami przypadki testowe pomagają wyjaśnić dokumentację. W większości przypadków przypadki testowe aplikacji są zbyt długie, aby można było je znaleźć w dokumentacji.

S.Lott
źródło
Fajnie byłoby zobaczyć przykład, do czego według ciebie jest odpowiednie, docstringa co nie. Właściwie podoba mi się docstring w terminach, które wyraźnie pokazują, jak używać interfejsu, ale używanie go zarówno do tego, jak i testów jednostkowych może nie pasować dobrze.
user1767754,
33

Kolejną zaletą testowania dokumentów jest upewnienie się, że kod działa tak, jak mówi dokumentacja. Po pewnym czasie zmiany oprogramowania mogą spowodować, że dokumentacja i kod będą działać inaczej. :-)

Jason Baker
źródło
6
+1 ode mnie - doskonały punkt
Doug
28

Pracuję jako bioinformatyk, a większość kodu, który piszę, to skrypty typu „jednorazowe, jedno zadanie”, kod, który będzie uruchamiany tylko raz lub dwa razy i który wykonuje jedno określone zadanie.

W tej sytuacji pisanie dużych artykułów może być przesadą, a testy doctesty są pożytecznym kompromisem. Są szybsze w pisaniu, a ponieważ są zwykle zawarte w kodzie, pozwalają zawsze mieć oko na to, jak kod powinien się zachowywać, bez konieczności otwierania kolejnego pliku. Jest to przydatne podczas pisania małego scenariusza.

Ponadto testy doctesty są przydatne, gdy musisz przekazać swój skrypt badaczowi, który nie jest ekspertem w programowaniu. Niektórym osobom bardzo trudno jest zrozumieć strukturę unittestów; z drugiej strony testy dokumentów są prostymi przykładami użycia, więc ludzie mogą je po prostu skopiować i wkleić, aby zobaczyć, jak z nich korzystać.

A więc wracając do mojej odpowiedzi: testy doctesty są przydatne, gdy trzeba napisać małe skrypty, a także przekazać je lub pokazać badaczom, którzy nie są informatykami.

dalloliogm
źródło
6
„Testy doctesty są przydatne, gdy trzeba pisać małe skrypty i kiedy trzeba je przekazać lub pokazać naukowcom, którzy nie są informatykami”. Doskonała uwaga. Robię to samo i programiści spoza języka Python są zawsze zdumieni, że dokumentację można wykonać.
Daniel Canas,
14

Jeśli dopiero zaczynasz z pomysłem testowania jednostkowego, zacznę od tego, doctestponieważ jest tak prosty w użyciu. Oczywiście zapewnia również pewien poziom dokumentacji. Aby uzyskać bardziej kompleksowe testy doctest, możesz umieścić testy w zewnętrznym pliku, aby nie zaśmiecać dokumentacji.

Sugerowałbym, unittestjeśli pochodzisz z przeszłości korzystającej z JUnit lub czegoś podobnego, gdzie chcesz mieć możliwość pisania testów jednostkowych w taki sam sposób, w jaki byłeś gdzie indziej.

Greg Hewgill
źródło
4
Zachęcano mnie do pójścia w tym kierunku ( doctestna początku), ale w końcu tego pożałowałem. W przypadku nietrywialnych przypadków testowych zgubiłem podświetlanie składni i automatyczne uzupełnianie w moim edytorze. Gdy testy znajdowały się w osobnym pliku, nie mogłem już uruchomić ich bezpośrednio z edytora - za każdym razem musiałbym zmieniać kontekst z powrotem na odpowiedni plik źródłowy.
Dziwne myślenie
7

Używam wyłącznie unittest; Myślę, że doctest za bardzo zaśmieca główny moduł. Ma to prawdopodobnie związek z pisaniem dokładnych testów.

Tony Arkles
źródło
7

Korzystanie z obu jest prawidłową i raczej prostą opcją. doctestModuł dostarcza DoctTestSuitei DocFileSuitemetod, które tworzą unittest kompatybilne TestSuite z modułem lub pliku, odpowiednio.

Dlatego używam obu i zazwyczaj używam doctest do prostych testów z funkcjami, które wymagają niewielkiej konfiguracji lub nie wymagają jej wcale (proste typy argumentów). Właściwie myślę, że kilka testów doctest pomaga udokumentować funkcję, a nie ją odwracać.

Ale w przypadku bardziej skomplikowanych przypadków i bardziej wszechstronnego zestawu przypadków testowych używam unittest, który zapewnia większą kontrolę i elastyczność.

davidavr
źródło
7

Nie używam doctest jako zamiennika unittest. Chociaż trochę się pokrywają, oba moduły nie mają tej samej funkcji:

  • Używam unittestframeworka do testów jednostkowych, co oznacza, że ​​pomaga mi to szybko określić wpływ jakiejkolwiek modyfikacji na resztę kodu.

  • Używam doctestjako gwarancji, że komentarze (a mianowicie dokumenty) są nadal aktualne dla aktualnej wersji kodu.

Szeroko udokumentowane korzyści płynące z rozwoju sterowanego testami, z których czerpię unittest. doctestrozwiązuje znacznie bardziej subtelne niebezpieczeństwo, że nieaktualne komentarze wprowadzają w błąd konserwację kodu.

rahmu
źródło
4

Prawie nigdy nie korzystam z doctestów. Chcę, aby mój kod samodokumentował się, a dokumenty zawierają dokumentację dla użytkownika. IMO dodając setki linii testów do modułu sprawia, że ​​dokumenty są znacznie mniej czytelne. Uważam również, że testy jednostkowe są łatwiejsze do zmodyfikowania w razie potrzeby.

JimB
źródło
4

Doctestczasami może prowadzić do błędnego wyniku. Zwłaszcza, gdy wyjście zawiera sekwencje ucieczki. Na przykład

def convert():
    """
    >>> convert()
    '\xe0\xa4\x95'
    """
    a = '\xe0\xa4\x95'
    return a
import doctest
doctest.testmod()

daje

**********************************************************************
File "hindi.py", line 3, in __main__.convert
Failed example:
    convert()
Expected:
    'क'
Got:
    '\xe0\xa4\x95'
**********************************************************************
1 items had failures:
   1 of   1 in __main__.convert
***Test Failed*** 1 failures. 

Nie sprawdza też typu wyjścia. Po prostu porównuje ciągi wyjściowe. Na przykład stworzył wymierny typ, który wyświetla się tak samo jak liczba całkowita, jeśli jest liczbą całkowitą. Następnie załóżmy, że masz funkcję, która zwraca wartość wymierną. Tak więc test doc nie rozróżni, jeśli wynik jest wymierną liczbą całkowitą lub liczbą całkowitą.

Szorstki
źródło
5
Możesz użyć surowych docstrings ( r""" ... """), aby rozwiązać pierwszy problem.
icktoofay
Działa dobrze w Pythonie 3.4. Aby działał również w Pythonie 2.7, użyj '\\xe0\\xa4\\x95'w swoim docstring.
Cees Timmerman
Zauważyłem również, że literały Unicode również nie działają z doctestami (nawet z odpowiednią linią komentarza „kodującego utf-8” na górze pliku. Generalnie doctesty nie są tak dobrze obsługiwane jak testy unittest, więc jest kilka błędów to nie zostanie naprawione
RichVel
2

Wolę systemy oparte na wykrywaniu („nos” i „py.test”, obecnie używam tego pierwszego).

doctest jest przyjemny, gdy test jest również dobry jako dokumentacja, w przeciwnym razie zbytnio zaśmiecają kod.

leniwy 1
źródło
nos wygląda niesamowicie użytecznie; Nie miałem jeszcze okazji go użyć, ale mam duże nadzieje :)
Tony Arkles,
Nos to najłatwiejszy w użyciu framework testowy, IMO. To sprawia, że ​​pisanie i uruchamianie przypadków testowych jest prawie łatwe.
Kamil Kisiel,