Jaka jest decydująca zaleta testów jednostkowych w porównaniu z testami integracyjnymi?
To fałszywa dychotomia.
Testy jednostkowe i integracyjne służą dwóm podobnym, ale różnym celom. Celem testów jednostkowych jest upewnienie się, że metody działają. W praktyce testy jednostkowe upewniają się, że kod spełnia warunki określone w testach jednostkowych. Jest to widoczne w sposobie projektowania testów jednostkowych: w szczególności określają, co powinien zrobić kod, i twierdzą, że kod to robi.
Testy integracyjne są różne. Testy integracyjne sprawdzają interakcję między komponentami oprogramowania. Możesz mieć komponenty oprogramowania, które przejdą wszystkie ich testy i nadal nie przejdą testów integracji, ponieważ nie działają prawidłowo.
Jeśli jednak testy jednostkowe mają decydującą przewagę, jest to następujące: testy jednostkowe są znacznie łatwiejsze do skonfigurowania i wymagają znacznie mniej czasu i wysiłku niż testy integracyjne. Przy prawidłowym stosowaniu testy jednostkowe zachęcają do opracowania kodu „testowalnego”, co oznacza, że końcowy wynik będzie bardziej niezawodny, łatwiejszy do zrozumienia i łatwiejszy do utrzymania. Testowalny kod ma pewne cechy, takie jak spójny interfejs API, powtarzalne zachowanie i zwraca wyniki, które są łatwe do potwierdzenia.
Testy integracyjne są trudniejsze i droższe, ponieważ często potrzebne są skomplikowane kpiny, złożona konfiguracja i trudne stwierdzenia. Na najwyższym poziomie integracji systemu wyobraź sobie próbę symulacji interakcji człowieka w interfejsie użytkownika. Całe systemy oprogramowania są poświęcone tego rodzaju automatyzacji. I szukamy automatyzacji; testy na ludziach nie są powtarzalne i nie skalują się tak jak testy automatyczne.
Wreszcie, testy integracyjne nie gwarantują pokrycia kodu. Ile kombinacji pętli kodu, warunków i gałęzi testujesz w testach integracyjnych? Czy naprawdę wiesz Istnieją narzędzia, których można użyć w testach jednostkowych i testowanych metodach, które podadzą, ile masz pokrycia kodu i jaka jest jego cykliczna złożoność. Ale naprawdę działają dobrze tylko na poziomie metody, w której przeprowadzane są testy jednostkowe.
Jeśli Twoje testy zmieniają się za każdym razem, gdy dokonujesz refaktoryzacji, jest to inny problem. Testy jednostkowe powinny polegać na udokumentowaniu tego, co robi twoje oprogramowanie, udowodnieniu, że to robi, a następnie udowodnieniu, że robi to ponownie, gdy refaktoryzujesz podstawową implementację. Jeśli twój interfejs API ulegnie zmianie lub potrzebujesz metod, które zmienią się zgodnie ze zmianą w projekcie systemu, tak właśnie powinno się stać. Jeśli to się często zdarza, najpierw napisz testy, zanim napiszesz kod. Zmusi cię to do zastanowienia się nad ogólną architekturą i pozwoli ci pisać kod z już ustanowionym API.
Jeśli spędzasz dużo czasu, pisząc testy jednostkowe dla takiego trywialnego kodu
public string SomeProperty { get; set; }
powinieneś ponownie przeanalizować swoje podejście. Testowanie jednostkowe powinno sprawdzać zachowanie, aw powyższym wierszu kodu nie ma żadnego zachowania. Jednak stworzyłeś gdzieś zależność w swoim kodzie, ponieważ ta właściwość prawie na pewno będzie przywoływana gdzie indziej w twoim kodzie. Zamiast tego, zastanów się nad napisaniem metod, które akceptują potrzebną właściwość jako parametr:
public string SomeMethod(string someProperty);
Teraz twoja metoda nie ma żadnych zależności od czegoś poza sobą i jest teraz bardziej testowalna, ponieważ jest całkowicie samodzielna. To prawda, że nie zawsze będziesz w stanie to zrobić, ale przesuwa twój kod w kierunku większej możliwości testowania i tym razem piszesz test jednostkowy dla rzeczywistego zachowania.