Dodawanie testów jednostkowych do starszego kodu [zamknięte]


79

Czy kiedykolwiek dodałeś testy jednostkowe po fakcie do starszego kodu? Jak skomplikowany był kod i jak trudno wszystko odgiąć i wyszydzić? Czy efekt końcowy był wart zachodu?


4
Sprawdzę „Efektywna praca ze starszym kodem”. Mam nadzieję, że dostanę kilka dobrych wskazówek, jak pisać opakowania dla wszystkich tych statycznych zależności!
— BuckeyeSoftwareGuy

Odpowiedzi:


57

Najlepszym sposobem, jaki znalazłem, jest przyrostowe dodawanie testów jednostkowych, a nie po prostu wskakiwanie i mówienie, że teraz będziemy testować jednostkowo aplikację.

Tak więc, jeśli zamierzasz dotknąć kodu, w celu usunięcia błędów lub refaktoryzacji, najpierw napisz testy jednostkowe. W przypadku błędów testy jednostkowe pomogą udowodnić, gdzie jest problem, ponieważ można go powielić.

W przypadku refaktoryzacji będziesz chciał napisać testy jednostkowe, ale może się okazać, że testu nie da się napisać, więc może zajść potrzeba znalezienia wysokiego poziomu, który wywoła funkcję, która zostanie refaktoryzowana, i przetestuj tę część. Następnie, podczas refaktoryzacji funkcji ofensywnej, napisz testy, aby upewnić się, że działa tak, jak powinno.

Nie ma na to prostego sposobu.

To pytanie może pomóc w uzyskaniu dalszych sugestii. Jak wprowadzić testy jednostkowe do dużej, starszej (C / C ++) bazy kodu?


8
+1 za stopniowe dodawanie testów.
— TrueWill

42

Książka Michaela Feathersa „Efektywna praca z dotychczasowym kodem” to cała książka na ten temat. Michael stwierdza, że ​​wprowadzenie testów dla starszego kodu jest często zbyt trudne, ponieważ nie ma on struktury umożliwiającej testowanie. To, co najbardziej wyciągnąłem z książki, to kilka wzorców nazwanych „Funkcje kiełkowania” i „Klasy kiełkowania”. Funkcja kiełkowania to taka, która zawiera zmiany, które musisz wprowadzić w kodzie. Następnie testujesz jednostkowo tylko te funkcje. Klasa kiełków to ten sam pomysł, ale nowa funkcjonalność jest zawarta w klasie.


10

Tak, i ogólnie jest to bolesne. Często musiałem zamiast tego pisać testy integracyjne.

Książka The Art of Unit Testing zawiera kilka dobrych rad na ten temat. Zaleca również książkę „ Skuteczna praca z dotychczasowym kodem” ; Nie przeczytałem jeszcze tego ostatniego, ale jest na moim stosie.

EDYCJA: Ale tak, nawet minimalne pokrycie kodu było warte zachodu. Dało mi to pewność siebie i zabezpieczenie przed refaktoryzacją kodu.

EDYCJA: Przeczytałem Praca efektywnie ze starym kodem i jest doskonała.


4
+1 za „Efektywną pracę z dotychczasowym kodem”: pełna cennych porad; w rzeczywistości warto go przeczytać nawet w środowiskach od podstaw, po prostu jako świetne źródło informacji o konstruowaniu kodu w celu testowania.
— itowlson

1
+1 za pomysł zamiany testów jednostkowych na testy integracyjne. Przy odpowiednim kpieniu te pierwsze są wystarczająco dobre, dość często
— DVK

7

Przyjrzyj się także nowemu podejściu w obszarze testowania jednostkowego starszego kodu - projekt Asis , jest inspirowany przez ApprovalTests projektem i dzieli się jego kluczowymi koncepcjami.

Jak wspomniano o podejściu ApprovalTests w tym artykule :

Często masz ogromny, starszy projekt kodu, w którym nie masz żadnych testów, ale musisz zmienić kod, aby zaimplementować nową funkcję lub refaktoryzację. Ciekawą rzeczą w starym kodzie jest to, że działa! Działa przez lata, bez względu na to, jak jest napisane. I to jest bardzo duża zaleta tego kodu. Dzięki zatwierdzeniom za pomocą tylko jednego testu możesz uzyskać wszystkie możliwe wyniki (HTML, XML, JSON, SQL lub cokolwiek to może być) i zatwierdzić, ponieważ wiesz - to działa! Po ukończeniu takiego testu i zatwierdzeniu wyniku, jesteś naprawdę dużo bezpieczniejszy z refaktoryzacją, ponieważ teraz „zablokowałeś” wszystkie istniejące zachowania.

Narzędzie Asis polega właśnie na utrzymywaniu starszego kodu poprzez automatyczne tworzenie i uruchamianie testów charakteryzacji.

Aby uzyskać więcej informacji, zobacz


Jak to nie ma więcej głosów za? Jeśli repozytorium robi to, co twierdzi, że robi, powinna to być wybrana odpowiedź.
— lolololol ol

Czy przy okazji radzi sobie ze skutkami ubocznymi w funkcjach? Czy można rozwiązać ten problem?
— lolololol ol

5

Jedną z alternatyw dla testów jednostkowych, również wprowadzoną w sekcji Efektywna praca ze starszym kodem, są testy charakteryzacji . Z takimi testami miałem ciekawe wyniki. Są łatwiejsze do skonfigurowania niż testy jednostkowe podczas testowania z punktu, niż można je przetestować (zwane szwem). Wadą jest to, że gdy test się nie powiedzie, masz mniej wskazówek co do lokalizacji problemu, ponieważ testowany obszar może być znacznie większy niż w przypadku testów jednostkowych. Logowanie pomaga tutaj.


Struktury testów jednostkowych, takie jak te z rodziny xUnit, mogą być używane do pisania testów charakteryzacji.

W takich testach, pisanych po faktach, asercje weryfikują bieżące zachowanie kodu. W przeciwieństwie do testów jednostkowych nie udowadniają, że kod jest poprawny, po prostu określają (charakteryzują) bieżące zachowanie kodu.

Proces jest podobny jak w przypadku TDD:

  • napisz test dla części kodu
  • wykonaj - niepowodzenie
  • napraw test z zaobserwowanego zachowania kodu
  • wykonaj to - przejdź
  • powtarzać

Testy zakończą się niepowodzeniem, jeśli zmodyfikujesz zewnętrzne zachowanie kodu. Zewnętrzne zachowanie kodu? brzmi znajomo ? Tak jest, oto jesteśmy. Teraz możesz refaktoryzować kod.

Oczywiście ryzyko zależy od zakresu badań charakterystyk.


5

Zapoznaj się z bezpłatną biblioteką narzędzi do testów jednostkowych typu open source, ApprovalTests . Jeśli jesteś programistą .NET, twórca, Llewellyn Falco, nakręcił serię filmów pokazujących, w jaki sposób używa ApprovalTests do ulepszenia testów jednostkowych zarówno dla nowego, jak i starszego kodu.


4

Jeśli planujesz refaktoryzację starszego kodu, utworzenie tych testów jednostkowych jest koniecznością. Nie martw się o mockowanie lub stubbing - martw się o testowanie danych wejściowych i wyjściowych systemu, aby zmiany lub refaktoryzacja nie zakłócały bieżącej funkcjonalności.

Nie będę cię okłamywał, doposażenie testów jednostkowych do starszego kodu jest trudne - ale warto.


Zacząłem tworzyć testy jednostkowe dla starszego kodu, nad którym pracowałem. Jednak zdałem sobie sprawę, że piszę testy integracyjne, a nie jednostkowe, ponieważ tworzę rzeczywiste dane i wstawiam je do bazy danych. Nie widzę sposobu na tworzenie czystych mocków i stubów dla tego starszego kodu, ponieważ w ogóle nie jest on ustrukturyzowany do testowania.
— Vin Shahrdar

1

Już jakiś czas temu mówiłem o idei Reversed Tests Pyramid in Legacy Code na XPDays http://xpdays.com.ua/archive/xp-days-ukraine-2012/materials/legacy-code/

Ta prezentacja powinna odpowiedzieć na pytanie, dlaczego tak ważne jest czasami rozpoczęcie od testów integracyjnych / funkcjonalnych lub nawet testów akceptacyjnych wysokiego poziomu podczas pracy ze starszym kodem. A potem powoli, krok po kroku, wprowadzając testy jednostkowe. Nie ma przykładów kodu - przepraszam, ale kilka z nich można znaleźć w książce Michaels Feathers „Efektywna praca z Legacy Code”.

Możesz również sprawdzić Legacy Code Retreat http://www.jbrains.ca/legacy-code-retreat i poszukać tego spotkania w Twojej okolicy.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.