Podążam religijnie za TDD. Moje projekty zazwyczaj mają 85% lub więcej pokrycia testowego, z sensownymi przypadkami testowymi.
Dużo pracuję z HBase , a główny interfejs klienta, HTable, jest bardzo trudny do wyszydzenia. Pisanie moich testów jednostkowych zajmuje mi 3 lub 4 razy więcej niż pisanie testów, które używają aktywnego punktu końcowego.
Wiem, że filozoficznie testy wykorzystujące symulacje powinny mieć pierwszeństwo przed testami wykorzystującymi aktywny punkt końcowy. Ale szydzenie z HTable jest poważnym bólem i nie jestem pewien, czy oferuje dużą przewagę nad testowaniem na żywo instancji HBase.
Wszyscy w moim zespole uruchamiają jedno-węzłowe wystąpienie HBase na swojej stacji roboczej, a my mamy jedno-węzłowe wystąpienia HBase działające na naszych urządzeniach Jenkins, więc nie jest to kwestia dostępności. Testy na żywo punktów końcowych trwają oczywiście dłużej niż testy wykorzystujące symulacje, ale tak naprawdę nas to nie obchodzi.
W tej chwili piszę na żywo testy punktów końcowych ORAZ testy próbne dla wszystkich moich klas. Chciałbym porzucić te kpiny, ale nie chcę, aby jakość spadła.
Co wszyscy myślicie
źródło
Odpowiedzi:
Moim pierwszym zaleceniem byłoby, aby nie kpić z typów, których nie posiadasz . Wspomniałeś, że HTable jest prawdziwym bólem do kpienia - być może powinieneś owinąć go w Adapter, który ujawnia 20% potrzebnych funkcji HTable, i kpić z opakowania w razie potrzeby.
Biorąc to pod uwagę, załóżmy, że mówimy o typach, które wszyscy posiadacie. Jeśli twoje symulacje oparte są na scenariuszach szczęśliwych ścieżek, w których wszystko idzie płynnie, nie stracisz nic, porzucając je, ponieważ testy integracyjne prawdopodobnie już testują dokładnie te same ścieżki.
Jednak izolowane testy stają się interesujące, gdy zaczniesz myśleć o tym, jak testowany system powinien reagować na każdą drobiazg, który może się zdarzyć zgodnie z umową jego współpracownika, niezależnie od konkretnego konkretnego obiektu, z którym rozmawia. To część tego, co niektórzy nazywają podstawową poprawnością . Może być wiele takich małych skrzynek i wiele innych kombinacji. W tym momencie testy integracyjne zaczynają być kiepskie, podczas gdy pojedyncze testy pozostaną szybkie i łatwe do zarządzania.
Aby być bardziej konkretnym, co się stanie, jeśli jedna z metod adaptera HTable zwróci pustą listę? Co jeśli zwróci wartość null? Co się stanie, jeśli zgłosi wyjątek połączenia? Należy określić w umowie adaptera, czy coś takiego mogłoby się zdarzyć, a każdy z jego konsumentów powinien być przygotowany na poradzenie sobie z tymi sytuacjami , stąd potrzeba ich testów.
Podsumowując: nie zobaczysz żadnego spadku jakości po usunięciu próbnych testów, jeśli przetestują dokładnie te same rzeczy, co testy integracyjne . Jednak próba wyobrazenia sobie dodatkowych izolowanych testów (i testów kontraktowych ) może pomóc w znacznym przemyśleniu interfejsów / kontraktów i podniesieniu jakości przez wyeliminowanie defektów, o których trudno byłoby pomyśleć i / lub które wolno testować za pomocą testów integracyjnych.
źródło
Myślę, że co najmniej, to punktem bieżącym trwającej kontrowersji wśród zwolenników TDD.
Mój osobisty pogląd wykracza poza to, by powiedzieć, że próbny test jest głównie sposobem na reprezentację formy umowy interfejsu ; idealnie psuje się (tzn. nie działa) wtedy i tylko po zmianie interfejsu . I jako taki, w rozsądnie silnie typowanych językach, takich jak Java, a przy użyciu wyraźnie zdefiniowanego interfejsu jest prawie całkowicie zbędny: kompilator już ci powie, czy zmieniłeś interfejs.
Głównym wyjątkiem jest sytuacja, w której używasz bardzo ogólnego interfejsu, być może opartego na adnotacjach lub refleksjach, że kompilator nie jest w stanie skutecznie użytkować policji automatycznie. Nawet wtedy powinieneś sprawdzić, czy istnieje sposób na programową weryfikację (np. Bibliotekę sprawdzającą składnię SQL), a nie ręcznie przy użyciu próbnych metod.
To właśnie ten drugi przypadek ma miejsce podczas testowania przy użyciu lokalnej „bazy danych” na żywo; Wdrożenie htable rozpoczyna się i stosuje znacznie bardziej kompleksową walidację umowy międzyfazowej, niż można sobie wyobrazić ręcznie.
Niestety, o wiele bardziej powszechnym zastosowaniem próbnych testów jest test, który:
Takie testy należy oczywiście usunąć na widok.
źródło
Ile dłużej trwa test oparty na punkcie końcowym niż test próbny? Jeśli jest znacznie dłuższy, to tak, warto zainwestować czas na pisanie testów, aby przyspieszyć testy jednostkowe - ponieważ będziesz musiał je uruchamiać wiele, wiele razy. Jeśli nie jest to znacznie dłuższe, mimo że testy oparte na punktach końcowych nie są „czystymi” testami jednostkowymi, o ile wykonują dobrą robotę testowania jednostki, nie ma powodu, aby być religijnym.
źródło
Zgadzam się całkowicie z odpowiedzią guillaume31, nigdy nie kpij z typów, których nie posiadasz!
Zwykle ból w teście (kpina ze złożonego interfejsu) odzwierciedla problem w twoim projekcie. Być może potrzebujesz pewnej abstrakcji między modelem a kodem dostępu do danych, na przykład z wykorzystaniem architektury heksagonalnej i wzorca repozytorium, który jest najczęstszym sposobem rozwiązania tego rodzaju problemów.
Jeśli chcesz wykonać test integracyjny w celu sprawdzenia rzeczy, zrób test integracyjny, jeśli chcesz wykonać test jednostkowy, ponieważ testujesz logikę, wykonaj test jednostkowy i odizoluj utrwalanie. Ale wykonując test integracji, ponieważ nie wiesz, jak odizolować swoją logikę od systemu zewnętrznego (lub ponieważ izolowanie jej bólu) to duży zapach, wybierasz integrację zamiast jednostki dla ograniczenia w projekcie, a nie dla prawdziwej potrzeby przetestować integrację.
Spójrz na tę rozmowę z Ianem Cooperem: http://vimeo.com/68375232 , mówi o architekturze heksagonalnej i testowaniu, mówi o tym, kiedy i co drwić, naprawdę inspirująca rozmowa, która rozwiązuje wiele pytań takich jak prawdziwe TDD .
źródło
TL; DR - Z mojego punktu widzenia zależy to od nakładu pracy na testy i od tego, czy lepiej byłoby zamiast tego wydać więcej na rzeczywisty system.
Długa wersja:
Kilka dobrych odpowiedzi tutaj, ale moje zdanie jest inne: testowanie jest działalnością gospodarczą, która musi się zwrócić, a jeśli czas, który poświęcisz, nie zostanie zwrócony na rozwój i niezawodność systemu (lub cokolwiek innego, co chcesz wydostać testów), być może dokonujesz złej inwestycji; zajmujesz się budowaniem systemów, a nie pisaniem testów. Dlatego kluczowe jest ograniczenie wysiłku w pisaniu i utrzymywaniu testów.
Na przykład niektóre główne wartości, które uzyskuję z testów, to:
Testowanie na działającym punkcie końcowym powinno nadal je zapewniać.
Niektóre wady testowania w odniesieniu do aktywnego punktu końcowego:
Gdybym był w takiej sytuacji, a wady nie wydawałyby się problemem, podczas gdy wyśmiewanie punktu końcowego znacznie spowolniło pisanie testu, w mgnieniu oka testowałbym w czasie rzeczywistym punkt końcowy na żywo. sprawdź ponownie po chwili, aby zobaczyć, czy wady nie okazują się problemem w praktyce.
źródło
Z perspektywy testowania istnieją absolutnie pewne wymagania:
To duże wyzwanie, gdy łączysz się z dowolnym źródłem, które utrzymuje stan poza twoimi testami. To nie jest „czysty” TDD, ale załoga Ruby on Rails rozwiązała ten problem w sposób, który może być przystosowany do twoich celów. Środowisko testowe szyn działało w ten sposób:
Cała ta praca została wbudowana w uprząż testową i działa dość dobrze. Jest o wiele więcej, ale podstawy tej rozmowy są wystarczające.
W różnych zespołach, z którymi pracowałem w czasie, dokonywaliśmy wyborów, które promowałyby testowanie kodu, nawet jeśli nie byłaby to najlepsza ścieżka. Idealnie byłoby zawinąć wszystkie wywołania do magazynu danych kontrolowanym przez nas kodem. Teoretycznie, jeśli którykolwiek z tych starych projektów uzyska nowe fundusze, moglibyśmy cofnąć się i przenieść je z bazy danych związanej z Hadoop, koncentrując naszą uwagę tylko na kilku klasach.
Ważne jest, aby nie mieszać się z danymi produkcyjnymi i upewnić się, że naprawdę testujesz to, co według Ciebie testujesz. Naprawdę ważne jest, aby móc zresetować usługę zewnętrzną do znanej linii bazowej na żądanie - nawet z poziomu kodu.
źródło