Jeśli mam już test integracyjny dla mojego programu i wszystkie zdały pomyślnie, to mam wrażenie, że zadziała. Jakie są zatem powody, aby pisać / dodawać testy jednostkowe? Ponieważ i tak muszę już pisać testy integracyjne, chciałbym napisać tylko test jednostkowy dla części, które nie są objęte testami integracyjnymi.
To, co znam, to przewaga testu jednostkowego nad testem integracyjnym
- Mały, a zatem szybki do uruchomienia (ale dodanie nowej jednostki w celu przetestowania czegoś jest już testowane przez test integracyjny, oznacza to, że mój komplet testowy staje się większy i dłuższy do uruchomienia)
- Łatwiej zlokalizuj błąd, ponieważ testuje tylko jedną rzecz (ale mogę rozpocząć test jednostkowy, aby zweryfikować każdą poszczególną część, gdy mój test integracji nie powiódł się)
- Znajdź błąd, który może nie zostać wykryty w teście integracji. np. błędy maskowania / kompensacji. (ale jeśli moje testy integracyjne przebiegną pomyślnie, co oznacza, że mój program będzie działał, nawet istnieje jakiś ukryty błąd. Więc znajdź / napraw te błędy nie mają tak naprawdę wysokiego priorytetu, chyba że zaczną przerywać przyszłe testy integracyjne lub powodować problemy z wydajnością)
I zawsze chcemy pisać mniej kodu, ale testy jednostkowe zapisu wymagają dużo więcej kodu (głównie próbnych obiektów konfiguracji). Różnica między niektórymi moimi testami jednostkowymi a testami integracyjnymi polega na tym, że w testach jednostkowych używam próbnego obiektu, aw testach integracyjnych używam rzeczywistego obiektu. Które mają dużo duplikacji i nie podoba mi się powielony kod, nawet w testach, ponieważ to dodaje narzut, aby zmienić zachowanie kodu (narzędzie refaktoryzacyjne nie może cały czas działać).
źródło
Odpowiedzi:
Przedstawiłeś dobre argumenty za i przeciw testom jednostkowym. Musisz więc zadać sobie pytanie: „ Czy dostrzegam wartość argumentów pozytywnych, które przewyższają koszty argumentów negatywnych? ” Z pewnością:
W mojej książce zalety przewyższają wady.
źródło
Nie widzę większej wartości w ponownym wdrażaniu istniejącej skrzynki testowej integracji jako niesprawiedliwej.
Testy integracyjne są często o wiele łatwiejsze do napisania dla starszych aplikacji, ponieważ zwykle funkcje, które mają być testowane, są ściśle ze sobą powiązane, więc jednostki testowe w izolacji (= niekwestionowanie) mogą być trudne / kosztowne / niemożliwe.
Moim zdaniem rozwój oparty na testach jest najskuteczniejszy, jeśli napiszesz testy jednostkowe przed właściwym kodem. W ten sposób kod, który spełnia testy, zostaje wyraźnie oddzielony przy pomocy minimum zewnętrznych odnośników, które można łatwo przetestować.
Jeśli kod już istnieje bez testów jednostkowych, zwykle jest dużo pracy, aby napisać testy jednostkowe później, ponieważ kod nie został napisany dla łatwego testowania.
Jeśli wykonasz TDD, kod będzie można łatwo przetestować.
źródło
unit-tests
i chcę dołączyćunit-tests
do niektórych części, czy uważasz, że lepiej jest najpierw napisaćintegration tests
dla starszego kodu. Kiedy to zostanie napisane, możesz rozłączyć ścisłe połączenie i stworzyć funkcje z interfejsami, które można przetestować? Skoro maszintegration-test
już napisane, możesz następnie sprawdzić na każdym etapie refaktoryzacji, czy nowa wersja kodu nadal działa zgodnie z oczekiwaniami?Testy integracyjne powinny jedynie weryfikować, czy kilka komponentów współpracuje zgodnie z oczekiwaniami. To, czy logika poszczególnych elementów jest dokładna, należy zweryfikować za pomocą testów jednostkowych.
Większość metod ma kilka możliwych ścieżek wykonania; pomyśl o zmiennych typu if-then-else, zmiennych wejściowych o nieoczekiwanych lub po prostu błędnych wartościach itp. Zwykle programiści myślą tylko o szczęśliwej ścieżce: normalnej ścieżce, która nie idzie źle. Ale jeśli chodzi o te inne ścieżki, masz dwie opcje: możesz pozwolić użytkownikowi końcowemu na zbadanie tych ścieżek poprzez działania podejmowane w interfejsie użytkownika i mieć nadzieję, że nie spowodują one awarii aplikacji, lub możesz napisać testy jednostkowe, które potwierdzają zachowanie tych innych ścieżek i podejmowanie działań w razie potrzeby.
źródło
Niektóre z powodów, które wskazałeś w swoim pytaniu, są naprawdę ważne i same w sobie mogą przemawiać za testami jednostkowymi, ale YMMV. Na przykład, jak często uruchamiasz zintegrowany zestaw testów? Moje doświadczenie ze zintegrowanymi testami jest takie, że prędzej czy później będą one tak wolne, że nie będziesz ich uruchamiał za każdym razem, gdy wprowadzasz zmiany, a czas między wstawieniem a wykryciem błędu wydłuży się.
Dużym błędem, który możesz popełnić, jest zaufanie
Find bug that may not be caught in integration test. e.g. masking/offsetting bugs.
to nie ważne. Czy spodziewasz się, że Twoi użytkownicy znajdą dla Ciebie błędy? Ufanie pokryciom uzyskanym ze zintegrowanych testów jest moim zdaniem niebezpieczne, możesz bardzo łatwo uzyskać wysoki procent pokrycia, ale w rzeczywistości testujesz bardzo mało.
Sądzę, że kanonicznym odniesieniem do zintegrowanych testów są posty JBrain:
http://www.jbrains.ca/permalink/integrated-tests-are-a-scam-part-1
na wypadek, gdybyś ich jeszcze nie przeczytał.
Wreszcie, IMO opinie, które można uzyskać z testów jednostkowych dla twojego projektu, są nieocenione. Błędem może być również osądzanie projektu na podstawie intuicji i poleganie na zintegrowanych testach.
źródło
Jeśli kiedykolwiek będziesz musiał modyfikować lub refaktoryzować kod, niezbędne są testy jednostkowe. Testy jednostkowe istnieją nie tylko w celu wykazania błędów w momencie pisania kodu, ale także w celu pokazania, kiedy pojawiają się nowe błędy, gdy więcej kodu zostanie napisane.
Tak, dużo lepiej jest najpierw napisać testy integracyjne i jednostkowe, ale ich posiadanie ma dużą wartość, nawet jeśli zostaną napisane później.
źródło