Czy powinienem refaktoryzować swoje testy jednostkowe, gdy wydobywam klasę z testowanego systemu?

13

Napisałem tę klasę, która robi kilka rzeczy (być może jest to naruszenie zasady pojedynczej odpowiedzialności). Teraz zdaję sobie sprawę, że jakaś inna część projektu potrzebuje fragmentu tej logiki, a sposób, w jaki ją ujawnię, polega na wyodrębnieniu klasy z mojego oryginalnego Testowanego Systemu.

Spodziewam się, że będę w stanie to zrobić bez zmiany kodu testowego, ale kiedy skończę, możesz argumentować, że test nie jest już testem jednostkowym . Będzie testować klasę oryginalną i klasę, którą wyodrębniłem. Innymi słowy, będę miał jeden przypadek testowy, ale dwa systemy będą testowane.

Czy powinienem ponownie kodować kod testowy po zakończeniu? IE: Utworzyć ExtractedClassTest i przenieść do niego wszystkie odpowiednie testy z OriginalClassTest? Wydaje się, że może to być trochę ryzykowne: mogę stracić trochę zasięgu w tym procesie, może to nie być tak proste jak przeniesienie testu, a w końcu przepisałbym kod testowy, który kiedyś działał, ale może już nie, itp.

Z drugiej strony, jeśli pozostawiam OriginalClassTest bez zmian, widzę, że jest to problem z utrzymaniem testu. To będzie trochę mylące, aby dowiedzieć się, gdzie są testy ExtractedClass. Twoje pierwsze wrażenie będzie takie, że nie istnieje. Z biegiem czasu, przy wielu refaktoryzacjach kodu produkcyjnego, może to stać się poważnym problemem.

Jestem nowy w TDD, dlatego potrzebuję porady eksperta. Dzięki!

Daniel Kaplan
źródło

Odpowiedzi:

7

Po obejrzeniu tej niesamowitej rozmowy „Ian Cooper: TDD, gdzie to wszystko poszło nie tak”, nie będę się zgadzał z @pdr. Myślę, że powinieneś zachować tylko oryginalne testy. Twoja zdolność do refaktoryzacji testowanego systemu bez przerywania, pisania lub zmieniania jakichkolwiek testów jest przede wszystkim celem pisania testów.

Gdybym miał przetestować wyodrębnioną klasę, testowałbym raczej implementację niż zachowanie. W rezultacie mój kod będzie trudniejszy do refaktoryzacji w przyszłości: te nowe testy prawdopodobnie zawiodą, nawet jeśli zachowanie nadal będzie działać.

Daniel Kaplan
źródło
6

Na czas trwania rozwoju, mieć oba. Zachowaj stare testy jako gwarancję, że niczego nie zepsułeś, napisz nowe testy (od zera), aby pomóc Ci zaprojektować klasy tak, jak powinny.

Na koniec przeprowadź i usuń wszystko, co nie działa w starych testach. Bądź ostrożny w tej analizie; nie usuwaj niczego, ponieważ uważasz, że powinno to być nieczynne. Pokaż sobie (lub komuś innemu lub gumowej kaczce), dlaczego nie jest już potrzebny. Przerwij test i upewnij się, że kolejny test się z nim zepsuje.

Wszystko, co pozostało w starych testach, powinno być rozpatrywane indywidualnie, ale przeważnie powinny zostać przepisane do nowej struktury.

Ponieważ masz rację, nie chcesz stracić koszmaru związanego z konserwacją. Ale nie chcesz mieć mniejszego zasięgu niż wcześniej.

pdr
źródło
1
Właśnie to zrobiłem i muszę powiedzieć, że to dość demotywujące. Mimo że moje zmiany były proste, zajęło mi to około 2 godzin, aby upewnić się, że poprawnie przebudowałem testy i nadal mam taki sam zasięg. Stało się oczywiste, że powinienem dodać kilka dodatkowych testów do nowego testu, aby upewnić się, że sprawdzam różne rzeczy. Wydaje mi się, że bardziej efektywne byłoby wyodrębnienie klasy i pozostawienie dwóch systemów do testowania. Czy ta ilość pracy sugeruje, że źle napisałem testy?
Daniel Kaplan
1
@tieTYT: Trudno odpowiedzieć na to pytanie bez siedzenia i patrzenia na ciebie. Czasami TDD wydaje się więcej pracy niż jest to warte. Innym razem przypominasz sobie, dlaczego tak się martwiłeś. A innym razem to Ty utrudniasz to. Nauczenie się odróżniać to duża część bycia dobrym w TDD.
pdr
Czy sądzisz, że w tym przypadku nie powinienem był ponownie przeprowadzać testów lub uważasz, że to mało prawdopodobne?
Daniel Kaplan
1
@tieTYT: Mało prawdopodobne, tak. Niemożliwe, nie.
pdr