Czy jest jakaś wartość w pisaniu testów jednostkowych kodu, który już działa podczas dziedziczenia aplikacji?

27

Oczywiście niektóre stare aplikacje nie mogą być lub są niezwykle trudne do przetestowania jednostkowego ze względu na sposób, w jaki zostały napisane.

Ale w miejscach, takich jak niektóre metody pomocnicze, które prawdopodobnie mogłyby być testowane jednostkowo, czy powinienem zawracać sobie głowę pisaniem testów jednostkowych?

Można powiedzieć, że można je pisać jak pies, ale jakkolwiek skomplikowana jest logika, próba czasu udowodniła, że ​​działa tak, jak powinna. Czy powinienem zawracać sobie głowę testem jednostkowym, jeśli powiem, że przeorganizowałem go, czy powinienem pisać testy jednostkowe, gdy tylko mam na to czas?

Czy ma to jakąś wartość?

Weź również pod uwagę, że definicja metody może być niejasna i być może będę musiał zbadać, co niektóre metody powinny faktycznie zrobić w danych warunkach.

RoboShop
źródło
4
Zrób sobie przysługę i przeczytaj Efektywna praca ze starszym kodeksem . Jeśli jest to cała książka poświęcona odpowiedziom na to i inne powiązane pytania.
Rein Henrichs,

Odpowiedzi:

15

Myślę, że z pewnością powinieneś napisać jak najwięcej testów dla aplikacji. Pomogą ci nauczyć się podstawy kodu i przygotują cię do ewentualnego refaktoryzacji lub nowego rozwoju.

W tym scenariuszu można napisać kilka rodzajów testów, z których każdy ma swoje zalety. Pisanie tych testów nauczy Cię wiele na temat aplikacji, z którą masz do czynienia.

Przede wszystkim, zanim rozpoczniesz pisanie testów poprawności, napisz testy, które wychwytują bieżące zachowanie , czy to dobre, czy złe. To całkiem bezpieczny zakład, że odkryjesz błędy w narożnikach lub w częściach kodu, które nie zostały dokładnie przetestowane przez uruchomienie programu. Nie martw się o to, co powinien zrobić kod, po prostu zapisz to, co robi. Idąc dalej, nie martw się czytaniem kodu lub spędzaniem poważnego czasu na ustaleniu, jaki powinien być wynik. Wystarczy uruchomić test i przechwycić dane wyjściowe w asercie.

To da ci solidną podstawę do zrozumienia, jak działa kod i gdzie mogą znajdować się główne punkty bólu lub słabe obszary. Jeśli odkryjesz błędy, możesz następnie podejść do ludzi z mocą, aby zdecydować, czy warto je naprawić, czy nie i podjąć te decyzje.

Następnie możesz napisać kilka większych (w zakresie) testów, które obejmują części kodu, które mogą nie być łatwe do przetestowania w jednostce, ale gdzie nadal byłoby ważne przetestowanie przepływów pracy w jak największym stopniu. Te testy przepływu pracy lub testy integracyjne , w zależności od tego, jak chcesz na nie spojrzeć, zapewnią dobrą podstawę do refaktoryzacji tych przepływów pracy, aby uczynić je bardziej testowalnymi i chronić cię, gdy trzeba będzie dodać nową funkcję, która może wpłynąć na istniejący przepływ pracy.

Z czasem stworzysz zestaw testów, które pomogą Ci lub następnej osobie, która ostatecznie odziedziczy aplikację.

Adam Lear
źródło
13

Widzę testy jednostkowe jako specyfikacje, a nie tylko testy. W konkretnym przypadku, o którym wspomniałeś, rzeczywista wartość przyjdzie, gdy przeprowadzisz test jednostkowy przed wprowadzeniem jakichkolwiek zmian w celu dostosowania do nowej specyfikacji. Jeśli zamierzasz zmienić odziedziczony kod, to najlepszym sposobem, jaki widzę, jest przeprowadzenie testów jednostkowych pod kątem funkcjonalności, nie tylko zapewni to siatkę bezpieczeństwa, ale także pomoże nam lepiej wyjaśnić, co robi ta konkretna jednostka. Może to również zmusić cię do przeprowadzenia badań, o których wspomniałeś, co jest dobre dla zrozumienia. Dlatego uważam, że należy przeprowadzić test jednostkowy modułu, zanim zostanie on poddany zmianie.

Vinod R.
źródło
Napisz testy w języku najwyższego poziomu, który będzie działał. Gdy zostaniesz poproszony o oszacowanie czasu na dokonanie zmiany, podaj czas potrzebny na napisanie brakujących testów. Dokonanie zmiany może potrwać dłużej, ale wprowadzisz znacznie mniej błędów w terenie.
kevin cline
8
 > Is there any value in writing unit tests for code that 
 > already works when inheriting applications?

NO . Z mojego doświadczenia wynika, że po napisaniu kodu produkcyjnego istnieje zły stosunek kosztów do korzyści, ponieważ pisanie kodu produkcyjnego jest mało prawdopodobne / trudne do znalezienia sposobów na testowanie kodu w oderwaniu bez intensywnego refaktoryzacji. Jedną z zalet programowania opartego na testach jest luźny kod. Jeśli później napiszesz testy, istnieje duże prawdopodobieństwo, że kod jest ściśle powiązany.

TAK, możesz napisać testy integracji dla aplikacji dla tych funkcji, w których planujesz wprowadzić zmiany. W ten sposób możesz przeprowadzić test regresji, aby sprawdzić, czy zmiany coś psują.

TAK Z punktu widzenia jakości i dewelopera warto mieć testy.

NIE z biznesowego punktu widzenia, ponieważ bardzo trudno jest sprzedać klientowi, że potrzebujesz czasu / pieniędzy, aby nie uzyskać prawdziwej wartości biznesowej, ale niejasna obietnica, że ​​zmiany biznesowe nie pogorszą sytuacji.

k3b
źródło
+1 za testy integracyjne zamiast testu jednostkowego w tym przypadku. Bardzo pragmatyczna rada
gbjbaanb
5

Jeśli to w ogóle możliwe, istnieje jeszcze więcej powodów, aby pisać testy dla istniejącego kodu, który „już działa”. Jeśli nie ma żadnych testów, istnieje duże prawdopodobieństwo, że kod jest pełen zapachów i można by go ulepszyć przy użyciu rozbudowanego refaktoryzacji; zestaw testowy pomoże ci refaktoryzować. Może nawet ujawnić, że oryginalny kod nie działa poprawnie; Pamiętam, jak napisałem test dla metody generującej raport sprzedaży i stwierdziłem, że nie oblicza się właściwie, więc sprzedaż była o kilka tysięcy dolarów większa niż w rzeczywistości i nikt nie wiedział, że kod jest w produkcji (na szczęście nie był to faktyczny finansowy koniec rzeczy, tylko szacunek raportu sprzedaży).

Oczywiście, ta rada ma zastosowanie tylko wtedy, gdy rzeczywiście można napisać testy. Z mojego doświadczenia wynika, że ​​podstawa kodu bez testów jest prawie niemożliwa do ponownego przetestowania, ponieważ musiałbyś przepisać połowę modułów kodu, aby były wystarczająco abstrakcyjne, aby w pierwszej kolejności obsługiwać testowanie, i nie będziesz w stanie tego zrobić.

Wayne Molina
źródło
Po co głosować za prawdą?
Wayne Molina,
4

Absolutnie tak , ponieważ testy jednostkowe nie powinny weryfikować poprawności, ale charakteryzują faktyczne zachowanie systemu. Zwłaszcza w przypadku starszego projektu wiele wymagań jest domyślnie zakodowanych w rzeczywistym zachowaniu.

Ta charakterystyka służy jako podstawa funkcjonalności. Nawet jeśli zachowanie jest niepoprawne z biznesowego punktu widzenia, można wykluczyć dalsze pogorszenie zachowania. Zdobycie przyczepności w starszym projekcie może być trudne, a to daje podstawę, dzięki której możesz iść do przodu bez pogarszania sytuacji.

Napisz więc wszystkie testy jednostkowe, jakie możesz. W przypadku kodu, którego nie można przetestować, należy ponownie przypisać kod do oddzielnych zależności, wprowadzając do kodu „szwy” - miejsca, w których można oddzielić kod, który chcesz przetestować, od kodu, którego nie chcesz testować.

Idee testów jednostkowych jako testów charakterystycznych i szwów są głównymi punktami w książce „ Skuteczne działanie ze starszym kodem” autorstwa Michael Feathers, książki, którą bardzo polecam.

Matthew Rodatus
źródło
2

Zastanawiałem się nad tym sam, ponieważ w naszym systemie jest dość dużo nieudokumentowanych, złych napisów, ale działających starszych kodów.

Masz rację:

Czy powinienem zawracać sobie głowę testem jednostkowym, jeśli powiem, że przeorganizowałem go, czy powinienem pisać testy jednostkowe, gdy tylko mam na to czas?

Jeśli wymagania się zmienią, myślę, że najcenniejsze byłoby napisanie testów jednostkowych. Jeśli nie, nie zawracałbym sobie głowy szczególnie, ponieważ nie byłbyś w stanie napisać odpowiednich testów, ponieważ nie znasz wszystkich warunków.

ilekroć mam czas?

Masz czas, kiedy ma on priorytet, prawda ?, więc i tak się nigdy nie wydarzy. :)

Michał
źródło
1

Czy próbujesz wykorzystać aspekty tej bazy kodu, które nie były wcześniej używane w aplikacji produkcyjnej? Najpierw napisz testy jednostkowe dla tych scenariuszy. Musisz mieć tutaj możliwość ustalenia priorytetów swojej pracy i myślę, że Art of Unit Testing miał w tym względzie kilka rad (w szczególności jak podejść do testowania starszych baz kodowych).

Justin Simon
źródło
1

Nie zakładaj, że wszystko działa tylko dlatego, że aplikacja jest uruchomiona ... zazwyczaj „test czasu” pokazuje tylko, że a) jeszcze nie znalazłeś pozostałych wad lub b) osoby, które znalazły nie zgłosili ich. (A może jedno i drugie.) I nawet kod, który prawdopodobnie działa teraz, może nie działać przy następnej zmianie.

Testy jednostkowe dają Ci pewność, że pewne funkcje pozostają nienaruszone, a jednocześnie zapewniają sposób na wykazanie tego w uzasadnionej liczbie przypadków. Jest to znacznie bardziej wartościowe niż „sprawdzanie i testowanie”, nawet w przypadku pojedynczej poprawki błędu. (Pogawędka przypomina bardziej integrację lub testowanie systemu, więc w tym sensie ręczne testowanie aplikacji może obejmować więcej niż same testy jednostkowe, ale to wciąż czas spędzany w nieefektywny sposób. Nawet niektóre metody automatyzacji tych testów są lepiej niż robić to ręcznie).

Zdecydowanie powinieneś pisać testy, kiedy zmieniasz kod, czy to naprawiający, czy refaktoryzujący. Możesz dobrze napisać testy, jeśli tylko zechcesz zaoszczędzić trochę czasu następnym razem, gdy będziesz musiał naprawić usterkę (i będzie następnym razem) ... chociaż w tym przypadku będziesz muszą zrównoważyć ten czas z oczekiwaniami ludzi, którzy udają, że oprogramowanie jest zawsze wolne od wad, a zatem czas poświęcony przyszłej konserwacji jest „zmarnowany”. (Nie oznacza to jednak, że należy zignorować bieżące harmonogramy.) W pewnym momencie, jeśli to zrobisz, będziesz mieć wystarczający zasięg, że możesz zacząć wykazywać wartość testowania w starszych aplikacjach, co może pomóc Ci wydać ten czas na przyszłe aplikacje, które ostatecznie powinny zwolnić czas na produktywny rozwój.

Dave DuPlantis
źródło
0

Z mojego serca Lala powiem „tak” i nie tylko to, ale zhakuj to, przebuduj i kontynuuj testowanie, ale upewnij się, że nie pozostaniesz w tyle w innych ważnych projektach. Jako pracujący programista, jeśli Twoja praca jest zagrożona lub jeśli kierownik poprosił cię o przejęcie własności, to tak. Jeśli zespół lub firma może ucierpieć, negocjuj ze swoim przełożonym, aby poinformować go, że konieczne jest przeprowadzenie testów, aby uchronić firmę przed katastrofą. Jeśli mówi: nie martw się, oznacza to, że nie masz szans ( delegacja winy to umiejętność zarządzania, więc upewnij się, że nie masz szans ... naprawdę!)

Powodzenia!

Armando
źródło