Czy testy jednostkowe naprawdę są wykorzystywane jako dokumentacja?

22

Nie mogę policzyć, ile razy czytam stwierdzenia w duchu „testy jednostkowe są bardzo ważnym źródłem dokumentacji testowanego kodu”. Nie przeczę, że są prawdziwe.

Ale osobiście nigdy nie używałem ich jako dokumentacji. W typowych ramach, których używam, deklaracje metod dokumentują ich zachowanie i to wszystko, czego potrzebuję. Zakładam, że testy jednostkowe wykonują kopię zapasową wszystkich informacji zawartych w tej dokumentacji, a także prawdopodobnie więcej wewnętrznych elementów, więc z jednej strony duplikuje dokumentację, z drugiej strony może dodać coś, co jest nieistotne.

Pytanie brzmi: kiedy testy jednostkowe są wykorzystywane jako dokumentacja? Kiedy komentarze nie obejmują wszystkiego? Przez programistów rozszerzających źródło? A co ujawniają, co może być przydatne i istotne, czego sama dokumentacja nie może ujawnić?

stijn
źródło
4
Nigdy nie myślałem o używaniu testu jednostkowego jako dokumentacji. Myślę, że testy jednostkowe są często nieczytelne, ponieważ wielu programistów nie poświęca czasu na ich jednoznaczne napisanie.
superM
10
Komentarze mogą być niepoprawne.
2
Wiem, że pytasz konkretnie o testy jednostkowe, ale chciałbym również zauważyć, że testy integracyjne / systemowe są również bardzo przydatną dokumentacją, tylko na innym poziomie
jk.
3
Widziałem testy jednostkowe, które można lepiej scharakteryzować jako „eksperymenty jednostkowe”. Ich zależność od czynników zewnętrznych była tak duża, że ​​uczyniły je niemal bezużytecznymi. Byli również bardzo niejasni. (Tak, mam długoterminowy cel, aby udoskonalić je, aby były lepsze, ale robię też inne rzeczy…)
Donal Fellows
4
@Ant testy jednostkowe wywołują prawdziwy kod i dokumentują oczekiwaną odpowiedź i porównują ją z rzeczywistą odpowiedzią. Nie ma znaczenia, czy wywołany kod jest poprawny, czy nie - testy dokumentują, jak go wywołać.

Odpowiedzi:

17

NIE są one absolutną dokumentacją referencyjną

Pamiętaj, że wiele z poniższych uwag dotyczy również komentarzy, ponieważ mogą one zsynchronizować się z kodem, na przykład testy (choć jest to mniej egzekwowalne).

Ostatecznie najlepszym sposobem na zrozumienie kodu jest posiadanie czytelnego działającego kodu .

Jeśli w ogóle możliwe i nie pisanie na stałe sekcji kodu niskiego poziomu lub szczególnie trudne warunki byłyby konieczne, dodatkowa dokumentacja będzie miała kluczowe znaczenie.

  • Testy mogą być niekompletne:
    • Interfejs API zmienił się i nie był testowany,
    • Osoba, która napisała kod, najpierw napisała testy najłatwiejszych metod testowania zamiast najważniejszych metod testowania, a następnie nie miała czasu na zakończenie.
  • Testy mogą być przestarzałe.
  • Testy mogą być zwierane w nieoczywisty sposób i faktycznie nie być wykonywane.

ALE WCIĄŻ SĄ POMOCNYM Uzupełnieniem dokumentacji

Jednakże, gdy masz wątpliwości co do tego, co robi konkretna klasa, zwłaszcza jeśli są dość długie, niejasne i brakuje komentarzy (znasz tego rodzaju ...), szybko próbuję znaleźć klasy testowe i sprawdzam:

  • co tak naprawdę próbują sprawdzić (daje podpowiedź na temat najważniejszych ciekawostek, z wyjątkiem sytuacji, gdy programista popełnił błąd, o którym mowa powyżej, polegający tylko na wdrożeniu „łatwych” testów),
  • a jeśli są przypadki narożne.

Ponadto, jeśli zostały napisane w stylu BDD , stanowią raczej dobrą definicję kontraktu klasy . Otwórz IDE (lub użyj grep), aby zobaczyć tylko nazwy metod i tada: masz listę zachowań.

Regresje i błędy też wymagają testów

Dobrą praktyką jest także pisanie testów regresji i raportów błędów: naprawiasz coś, piszesz test w celu odtworzenia sprawy. Patrząc na nie, jest to dobry sposób, aby znaleźć odpowiedni raport o błędzie i na przykład wszystkie szczegóły dotyczące starego problemu.

Powiedziałbym, że są dobrym uzupełnieniem prawdziwej dokumentacji i przynajmniej cennym zasobem w tym zakresie. To dobre narzędzie, jeśli jest właściwie używane. Jeśli zaczniesz testować na wczesnym etapie projektu i staniesz się nawykiem, MUSI to być bardzo dobra dokumentacja referencyjna. W przypadku istniejącego projektu o złych nawykach programistycznych, które już przywierają do podstawy kodu, należy postępować z nimi ostrożnie.

Haylem
źródło
Czy mogę zapytać, dlaczego zostałem odrzucony? Co Cię tam denerwuje lub z czym się nie zgadzasz?
haylem
2
Najlepsza część (IMO) twojego argumentu jest napisana najmniejszą czcionką - najlepszym sposobem na zrozumienie kodu jest przede wszystkim posiadanie czytelnego kodu. Zmieniłbym to na „czytelny i działający kod”, ale zgadzam się. Następnie, jeśli spojrzysz ponownie na testy jednostkowe - uruchomione testy są działającym kodem (i jak każdy kod, powinny być czytelne), więc jest to całkiem dobra (jeśli często zbyt lokalna) dokumentacja, jeśli jest dobrze wykonana.
Joris Timmermans
@MadKeithV: dzięki. Zaktualizowałem pod kątem „czytelnego i działającego kodu” i podniosłem ten poziom nieco wyżej.
haylem
11

Jedną z interpretacji jest to, że testy jednostkowe są „dokumentacją wykonywalną”. Możesz uruchomić testy jednostkowe na kodzie, a dowiesz się, czy nadal działa tak, jak w momencie, gdy testy zostały napisane jako zaliczone, czy nie. W ten sposób jednostka testuje „dokumentować” funkcjonalność systemu w pewnym momencie, w sposób wykonywalny.

Z drugiej strony rzadko kiedy faktycznie czytam kod testu jednostkowego jako „dokumentację”, aby zrozumieć funkcjonalność. Pojedynczy test jednostkowy jest zbyt umiejscowiony, specyficzny i abstrakcyjny, aby móc wiele powiedzieć o rzeczywistym systemie, który stoi za testowaną klasą.

Joris Timmermans
źródło
5

Jeśli dokumentacja znaczy chcę coś, aby dowiedzieć się, w jaki sposób kod działa wtedy testy jednostkowe są doskonałymi przykładami jak małe jednostki w pracach kodu zarówno z oczekiwaniami , przypadków brzegowych i błędy (aka bugs ) przypadkach. Ponadto testy mogą zostać utworzone przed napisaniem kodu, co stanowi podstawę tego, co powinien zrobić kod z punktu widzenia biznesu / wymagań.

Czy zastępują dokumentację? Nie.

Czy są przydatnym dodatkiem do dokumentacji? Tak.

Sardathrion - Przywróć Monikę
źródło
4

Testy jednostkowe widzę jako:

  • sposób udowodnienia, że ​​dokumentacja jest poprawna (zakładając, że dokumentacja jest zgodna z implementacją interfejsu API).
  • sposób na pokazanie deweloperowi, jak korzystać z określonej funkcji; urządzenia do testowania jednostkowego / same testy jednostkowe są zwykle na tyle małe, że można się z nich szybko nauczyć.
  • i oczywiście, aby wykryć każdy błąd regresji.

W pewnym stopniu można je postrzegać jako uzupełnienie istniejącej dokumentacji, ale nie jako dokumentację.

David Andreoletti
źródło
3

Odpowiem na twoje pytanie, zadając ci kolejne pytanie.

Jak często pracując z nowym interfejsem API / procedurą wystrzeliłeś pomoc, aby poszukać przykładowego kodu rzeczy, której próbujesz użyć? Jeśli nie przełączysz się na Google, aby wyszukać online próbki kodu?

Właśnie wtedy użyłbyś testów jednostkowych jako dokumentacji.

  • W rzeczywistości testy jednostkowe mogą być nieco bardziej rygorystyczne niż normalne przykłady kodu, ponieważ powinieneś mieć wiele testów (przykładów).
  • Mam nadzieję, że twoje testy jednostkowe ilustrują prawidłowe użycie. Np. Wyraźnie pokazują wszystkie istotne zależności albo poprzez zwykłe obiekty, albo przez fałszywe obiekty. (W przeciwnym razie nie są to szczególnie dobre testy jednostkowe.)
  • UWAGA: Jeśli twoje komentarze lub „normalna dokumentacja” zawierają przykłady kodu, w rzeczywistości naruszasz zasady OSUSZANIA. Te przykłady kodu mogą z czasem stać się niepoprawne , podczas gdy przy regularnie wykonywanych testach jednostkowych jest to znacznie mniejsze.
  • Jeśli testy jednostkowe są dokładne (zwykle duże, jeśli ), powinny one dostarczyć dodatkowe informacje:
    • Wszystkie znane przypadki brzegowe są wyraźnie zilustrowane.
    • Wszystkie oczekiwane wyjątki, które mogą zostać zgłoszone.
    • Wszystkie wcześniej znalezione błędy (jest to prawdopodobnie bardziej przydatne przy rozszerzaniu testowanego urządzenia niż podczas pisania nowego klienta dla urządzenia).
    • Wszystkie podstawowe reguły biznesowe związane z jednostką. (Jeśli w ogóle)

Podejrzewam, że istnieje kilka powodów, dla których testy jednostkowe nie są wykorzystywane jako dokumentacja, mimo że mogą być doskonałym uzupełnieniem bardziej tradycyjnej dokumentacji:

  • Zaryzykowałbym sugestię, że często same testy nie są wystarczająco dobrze napisane do tego celu. Inne odpowiedzi odnosiły się już do testów, które są:
    • Niekompletny.
    • Mylące. (Widziałem przypadki testowe, które nie wywołują bezpośrednio testowanej metody - wchodzisz 3/4 poziomów głęboko w stos wywołań, zanim zostanie wywołana, a warunki wstępne wywołania metody są rozproszone w różnych miejscach w złożonej hierarchii klas. )
    • Przestarzały. (zwykle testy powinny się nie powieść, gdy staną się nieaktualne, ale nie zawsze tak jest).
  • Zwykle w kodzie produkcyjnym dostępnych jest już wiele przykładów użycia, ilekroć pojawi się potrzeba podania przykładu.
  • Testowana jednostka jest tak dobrze napisana (samo dokumentowanie), że metody nie potrzebują przykładów. Chciałbym!
  • Z mojego doświadczenia jako programisty, jesteśmy skłonni wskoczyć na głęboki koniec i RTFM w najbliższy wtorek ...
  • Dokumentacja i komentarze, które naruszają zasadę SUCHEGO.
Rozczarowany
źródło
2

TL; DR Testy jednostkowe i komentarze API są komplementarne - niektóre rzeczy najlepiej opisać w kodzie, a inne w prozie.

Testy jednostkowe są głównie przydatne do dokumentowania specjalnych przypadków i warunków brzegowych, które są trudne (i kłopotliwe) do opisania w komentarzach API. Komentarze do interfejsu API są zwykle kierowane do osób, które chcą korzystać z interfejsu API.

Jeśli chcesz zmodyfikować kod, zwykle musisz wiedzieć o wiele więcej, a niektóre z nich trudno umieścić w komentarzach (i te komentarze szybko się zestarzeją). W takim przypadku test jednostkowy działa również jako dokumentacja.

Przykład: masz metodę m, (a, b)która wykonuje określone obliczenia. Ze względu na wymagania dotyczące zgodności z poprzednimi wersjami muszą być wprowadzane specjalne przypadki a=0i a=-1, ale tylko jeśli bma wartość NULL. Umieszczenie tego w komentarzu jest skomplikowane, pełne i może stać się nieaktualne, jeśli wymóg zostanie później usunięty.

Jeśli wykonasz kilka testów jednostkowych, które sprawdzą zachowanie m(0, NULL), m(-1, x)uzyskasz kilka korzyści:

  • Opis prawidłowego zachowania jest jasny, nieporozumienia są zredukowane
  • Ludzie nie mogą przeoczyć tego wymogu, gdy zmieniają kod, w przeciwieństwie do komentarza
Śleske
źródło
ale na przykład, jeśli takie zachowanie w ogóle nie jest udokumentowane w komentarzu, użytkownik może uzyskać nieoczekiwane wyniki dla tego przypadku krawędzi. Co nie jest do końca dobrą rzeczą.
stijn
@stijn: True. W takim przypadku najlepszym sposobem będzie prawdopodobnie krótka wzmianka o specjalnym przypadku w dokumentacji, a także testy jednostkowe pod kątem niechlujnych szczegółów.
sleske