Jakie są namacalne zalety prawidłowych testów jednostkowych w porównaniu z testem funkcjonalnym zwanym testami jednostkowymi

9

Projekt, nad którym pracuję, zawiera wiele starszych testów, które nie zostały odpowiednio wykpione. Z tego powodu jedyną zależnością, jaką posiada, jest EasyMock, który nie obsługuje statyki, konstruktorów z argumentami itp. Zamiast tego testy polegają na połączeniach z bazą danych i „uruchamiają” testy. Dodanie powermock do obsługi tych przypadków jest odrzucane jako zbyt kosztowne ze względu na potrzebę uaktualnienia istniejącego projektu w celu jego obsługi (kolejna dyskusja).

Moje pytania brzmią: jakie są REALNE namacalne korzyści płynące z właściwych testów jednostkowych, których mogę użyć, aby się wycofać? Czy są jakieś? Czy jestem po prostu zwolennikiem, mówiąc, że złe testy jednostkowe (nawet jeśli działają) są złe? Czy pokrycie kodu jest równie skuteczne?

Jackie
źródło
3
Być może kod, który piszesz, może skorzystać z pewnych zmian strukturalnych, aby uczynić go bardziej testowalnym. W naszej placówce intensywnie stosujemy testy jednostkowe bez szydzącego frameworka i wydaje się, że działa to całkiem dobrze dla nas.
Robert Harvey,
Wow, jestem pod wrażeniem. Chciałbym zobaczyć, jak sobie z tym poradzisz dzięki integracji z JAR stron trzecich. Czy masz jakieś przykłady lub linki?
Jackie,
1
Nie korzystamy z integracji JAR innej firmy. :) W razie potrzeby tworzymy jednak kody pośredniczące; kpiny z frameworków to tylko wygoda do osiągnięcia tego samego. Jeśli ten proces okaże się zbyt uciążliwy, ponownie zastanowimy się nad naszym podejściem do kodowania.
Robert Harvey,

Odpowiedzi:

8
  • Zasoby

    Potrzebujesz testowej bazy danych do uruchomienia testów. Sprzęt do uruchomienia bazy danych jest droższy niż korzystanie z powermock. Zwolnienie zasobów używanych do testowania jednostek w bazie danych oznacza, że ​​firma nie musi aktualizować serwera tak szybko.

  • Niezawodność

    Test może się nie powieść, ponieważ baza danych nie działa lub jest niespójna. Zgadnij co, twoje kompilacje nie powiodły się, ponieważ DBA zabrali serwer deweloperów w ciągu dnia, aby wykonać kilka aktualizacji (a teraz programiści próbują dowiedzieć się, co poszło nie tak w kodzie - jeśli nie jest to kod).

  • Dodatkowa konserwacja

    Testy można uruchamiać w dowolnej kolejności. Dodanie lub usunięcie testu nie powinno spowodować niepowodzenia zestawu testów. Uruchamianie z bazą danych oznacza, że ​​gdzieś jest jakiś stan (w bazie danych). Zazwyczaj testy te wymagają dodatkowej konserwacji, aby zapewnić, że baza danych utrzymuje odpowiedni stan do uruchomienia następnego testu.

  • Konkurencja

    Dwóch programistów przeprowadza testy jednostkowe w tym samym czasie. Posiadanie bazy danych oznacza, że ​​testy mogą kolidować z bazą danych. Rozwiązaniem tego byłoby sklonowanie bazy danych dla każdego uruchamianego testu, co jest zabronione w prawdziwej bazie danych. Co prowadzi do kolejnej opcji do rozważenia.

Rozważ także użycie HSQLDB z dowolnym dialektem bazy danych, której używasz. W ten sposób można utworzyć bazę danych w pamięci dla każdego testu. Uruchamia się test jednostkowy, konstruuje niezbędną bazę danych, ładuje dane, połączenie bazy danych z kodu łączy się z HSQLDB i działa z danymi testowymi.

Roc Martí
źródło
4

Moje pytania brzmią: jakie są REALNE namacalne korzyści płynące z właściwych testów jednostkowych, których mogę użyć, aby się wycofać?

Dobre testy jednostkowe to (według czystego kodu i gdzie indziej):

  • Szybki
  • Niezależny
  • Powtarzalne
  • Samo-walidacja
  • Aktualny

Brak prawdziwych testów jednostkowych narusza pierwsze trzy (i zwykle ostatnie). Prowadzi to do dość poważnych problemów:

  1. Twoje testy są wolne. Powolne testy uruchamiane są rzadko. Testy, które nie są uruchamiane, są prawie bezużyteczne.
  2. Twoje testy mogą zakończyć się niepowodzeniem z przyczyn niezwiązanych z testowanym kodem. To sprawia, że ​​znacznie trudniej jest dowiedzieć się, dlaczego testy zakończyły się niepowodzeniem, marnując czas i prowadząc ludzi do obwiniania środowiska, a nie kodu.
  3. W miarę zmiany bazy danych zmieniają się wyniki. Uzyskiwanie jakiejś bazy danych w znanym dobrym, spójnym i utrzymywanym stanie do testów jest żmudne, irytujące i podatne na błędy.

Zasadniczo brak izolacji w testach jednostkowych prowadzi do gorszych testów, które wymagają więcej czasu na pisanie, więcej czasu na inwestowanie i mniej zaufania do bazy kodu. To z kolei prowadzi do tego, że ludzie piszą mniej testów lub bardziej ignorują testy, co jest spiralą do chaosu.

Telastyn
źródło
2

Testy jednostkowe to tylko narzędzie, które pomaga deweloperowi w dostarczaniu niezawodnego kodu. Jeśli myślisz tak, jak myśli twój szef, będziesz w stanie go przekonać, czy to, co proponujesz, ma sens. Jeśli jednak przedstawisz go jako ewangelistę na wozie bolidu, nie otrzymasz przydzielonych zasobów. Musisz mu wyjaśnić, na czym on polega, poświęcając czas i zasoby na modernizację testów jednostkowych w starszej aplikacji.

Wspomniałeś o starszych testach - to implikuje starszy kod. Niestety dopasowanie testów jednostkowych do kodu, który nie został zaprojektowany do testowania jednostkowego, jest procesem trudnym, czasochłonnym i kosztownym. Sprawa biznesowa staje się jeszcze trudniejsza, jeśli masz testy, które zapewniają przydatne wyniki, a wszystko, co zamierzasz osiągnąć, to (z biznesowego POV) testy alternatywne zapewniające te same wyniki. Będziesz musiał skupić się na oszczędnościach kosztów (czasu) .....

Domyślam się, że nie będziesz w stanie przedstawić swojemu szefowi solidnego uzasadnienia biznesowego, ponieważ takiego nie ma.

mattnz
źródło
Zdecydowanie mogę zobaczyć, skąd pochodzisz, jednak bardziej szukałem sposobu na uzasadnienie tego przypadku. Martwienie się o jakość na marginesie jest nie tylko kosztowne.
Jackie,
1

Z tego, co opisałeś, wygląda na to, że nie lubisz szkieletu testowego A i chcesz przejść do szkieletu testowego B, z których oba działają. Ssij to i używaj tego, co istnieje i działa, nie tworząc więcej pracy wymyślając na nowo koło, abyś mógł użyć preferowanej struktury testowej.

Potrzeba więcej niż chęci wykorzystania najnowszego frameworku miesiąca, aby uzasadnić wyrzucenie istniejącego działającego kodu i poświęcenie ogromnej ilości czasu i pieniędzy dla zasadniczo zerowej korzyści dla użytkowników.

Ryathal
źródło
Nie do końca są to ramy, a bardziej pozwalające testom na dostęp do innych zasobów. Tym samym zasadniczo są to testy funkcjonalne zamiast testów jednostkowych. „Frameworki” to zarówno JUnit, jak i EasyMock (aczkolwiek starsze wersje). Sugerowałem dodanie NOWYCH ram zależnych.
Jackie,
1

Dobre testy jednostkowe zapewniają lokalizację. Testy funkcjonalne mogą powiedzieć, że „funkcja dodawania użytkownika jest zepsuta”, ale dobry test jednostkowy pokaże, że jest zepsuty, ponieważ ktoś zmienił pole USER.LAST_NAME w bazie danych na wartość inną niż null. Możliwe jest również bezpośrednie testowanie niewielkich zmian, zamiast konieczności korzystania ze złożonego środowiska testowego (które może wymagać ponownej inicjalizacji lub czyszczenia w przypadku niektórych testów).

TMN
źródło