Ocena, czy najpierw napisać test jednostkowy, czy test integracji w projektach typu błękitne niebo / prototyp

11

Zauważyłem ostatnio, kiedy wykonuję następujące typy projektów:

  • Na początku projektu
  • Praca na MVP / prototypie
  • Dodawanie funkcji, które nie są całkowicie zdefiniowane
  • Praca nad projektem na mniejszą skalę

Dla porównania pracuję nad projektem w języku Python, który obecnie zawiera ~ 1 000 wierszy kodu, w tym kilka komentarzy i wszystkie białe znaki.

Uważam, że znacznie łatwiej jest najpierw napisać testy integracyjne, pracować nad kodem, a potem, gdy interfejs API jest nieco zahartowany, faktycznie pracuje nad dodaniem testów jednostkowych. Rodzaje testów, które mogę wykonać na mojej mainfunkcji, że tak powiem, i są bardziej „end-to-end” niż cokolwiek innego.

Wynika to z faktu, że testy jednostkowe są naprawdę denerwujące, gdy API zmienia się dość szybko, co często ma miejsce w przypadku pracy nad projektem spełniającym którekolwiek lub większość powyższych kryteriów.

Czy takie podejście jest dobrym podejściem i jakie kryteria należy wziąć pod uwagę przy podejmowaniu decyzji, czy najpierw rozpocząć testy jednostkowe czy integracyjne dla tego rodzaju projektów? Czy brakuje mi wartości testowania jednostkowego tego rodzaju projektów, zanim interfejsy API zostaną bardziej zestalone?

kraina krańca
źródło
6
Rób wszystko, co dla ciebie najlepsze. Nie słuchaj ludzi, którzy mówią, że musisz pracować w określony sposób, aby być wydajnym: wiesz, kiedy jesteś wydajny, a kiedy nie. Nieważne, czy najpierw napiszesz testy integracyjne, czy testy jednostkowe. W przypadku niektórych projektów jeden sposób może być łatwiejszy, a w przypadku innych - drugi. To, co opisujesz, może być różnicą między projektowaniem odgórnym i oddolnym. Oba są przydatne, ale z góry na dół zwykle powstają lepsze projekty.
Frank Hileman,
@FrankHileman rzeczywiście, takie jest moje podejście. Ale ponieważ jestem ciekawy, chcę się upewnić, że stosuję właściwe podejście na wypadek, gdyby coś mi umknęło.
enderland
Najpierw skup się na specyfikacjach: częściach niekodowanych. Jakie są niezmienniki systemu? W ten sposób może się okazać, że musisz najpierw ustalić poziom niski lub poziom wysoki. Zależy, gdzie znajdują się najbardziej krytyczne lub ryzykowne algorytmy. Najpierw spróbuj je usunąć. To jest podstawowe zarządzanie ryzykiem.
Frank Hileman,
1
W przypadku pracy nad prototypem nie jest w ogóle pisanie testów. Celem prototypu jest sprawdzenie działającego pomysłu. Wdrożenie prototypu pomoże rozpoznać oczekiwany projekt aplikacji.
Fabio,
To się nazywa rozwój zewnętrzny. Możesz zapoznać się z następującą książką, która dokładnie to robi: amazon.com/dp/0321503627
Eternal21

Odpowiedzi:

7

Czy brakuje mi wartości testowania jednostkowego tego rodzaju projektów, zanim interfejsy API zostaną bardziej zestalone?

Nie. Dobrze ci idzie.

Dwa główne cele TDD to:

  • Definiowanie interfejsów według rzeczywistego użycia, a nie wewnętrznej implementacji 1
  • Maksymalizacja zasięgu testu

Pokrycie testowe może być dość dobrze zmaksymalizowane w każdym kierunku. Oznacza to, że niezależnie od tego, czy najpierw testujesz małe , izolowane jednostki, czy duże , „zintegrowane” jednostki, masz możliwość napisania testów przed implementacją.

To, co zyskujesz, pisząc najpierw testy wyższego poziomu („integracji”), to jak to robisz, pewność, że interfejsy i interakcje wyższego poziomu są również definiowane przede wszystkim na podstawie ich użycia, a nie ich wewnętrznych implementacji.

Ten sam efekt można w dużej mierze osiągnąć przy dobrym „architekturze” i tworzeniu diagramów. Ale te testy na wysokim poziomie często mogą ujawnić rzeczy, które przeoczyłeś na swoich diagramach - lub że popełniłeś błąd w pracy nad „architekturą”.


Jeśli tak naprawdę nie robisz TDD (lub czegoś podobnego), kolejność pisania testów nie ma większego znaczenia. Interfejsy już istnieją w momencie testowania, więc jest znacznie mniej prawdopodobne, że twoje testy coś zmienią - będą służyć jedynie do ochrony przed konkretnymi przełamującymi zmianami.

Ale jeśli martwisz się budowaniem implementacji z góry na dół w porównaniu do buttom-up, pierwszy punkt wypunktowania nadal ma duży wpływ. Kod wysokiego poziomu pomaga zdefiniować interfejsy niskiego poziomu. Podczas gdy, jeśli interfejsy niskiego poziomu zostaną zapisane jako pierwsze (lub w inny sposób już istnieją), kod wysokiego poziomu jest na ich łasce ...


1. Dotyczy to również sytuacji, gdy nie wykonujesz pełnego TDD. Nawet jeśli piszesz 1 lub 2 testy przed implementacją, te 1 lub 2 testy mogą pomóc Ci zdefiniować lub udoskonalić interfejsy, zanim będzie za późno!

svidgen
źródło
1

Pracowałem tak, jak ty. I nie powiem ci, że nie możesz. Ostrzegam cię przed czymś, na co możesz natknąć się.

Kiedy każdy test jednostkowy jest po prostu modernizacją, trudno jest nauczyć się, jak je uelastyczniać. Zwykle są niczym więcej niż testami regresji. Ponieważ nigdy nie używałeś ich do refaktoryzacji, bardzo łatwo jest napisać testy, które faktycznie utrudniają refaktoryzację. To wymyka się spod kontroli, dopóki nie stracisz wszelkiej wiary w TDD.

Jednak już nad czymś pracujesz. Nie powiem ci, żebyś przestał. Powiem, że warto zacząć od czegoś innego, co masz czas na zbadanie i śledzenie cyklu czerwonego zielonego reaktora od samego początku. Upewnij się, że faktycznie używasz testów, aby pomóc Ci dokonać refaktoryzacji. Dopóki nie opanujesz tego sposobu pracy, używaj go oszczędnie w czymś, co jest ważne. Jest to zupełnie inny sposób na kodowanie i wymaga przyzwyczajenia się. Robienie tego w połowie drogi nikomu nie przyniesie pożytku.

To mówi

Uważam, że znacznie łatwiej jest najpierw napisać testy integracyjne, pracować nad kodem, a potem, gdy interfejs API jest nieco zahartowany, faktycznie pracuje nad dodaniem testów jednostkowych. Rodzaje testów, które mogę wykonać na głównej funkcji, że tak powiem, i są bardziej „end-to-end” niż cokolwiek innego.

Zrozum, że test jednostkowy NIE jest po prostu testem, który działa na jedną klasę. Tak długo, jak interfejs API, nad którym pracujesz, można przetestować, nie wykonując żadnej z poniższych czynności:

  • Mówi do bazy danych
  • Komunikuje się przez sieć
  • Dotyka systemu plików
  • Nie może działać w tym samym czasie, co inne testy jednostkowe
  • Musisz wykonać specjalne czynności w swoim środowisku (np. Edytować pliki konfiguracyjne), aby je uruchomić.

Michael Feathers: zbiór zasad testowania jednostkowego

Więc jeśli twój kompleksowy test obejmuje więcej niż jeden obiekt, to jest w porządku. To jest testowanie jednostkowe, a nie testowanie obiektowe.

Podobnie jak prywatne metody nie muszą być już testowane, tak jak testowane są publiczne metody, które ich używają, tak obiekty nie muszą być początkowo opracowywane pod własną wiązką testową. Tylko wtedy, gdy obiekty są rozważane do użycia niezależnie od historii typu end-to-end, naprawdę muszą być traktowane tak, jakby miały własny interfejs i zachowanie, aby to potwierdzić. Jeśli zachowujesz ostrożność, upubliczniasz te obiekty. W ten sposób nie składasz żadnych obietnic, których nie przetestowałeś.

candied_orange
źródło