Obecnie uczę się o TDD i staram się wprowadzić go w życie w moich osobistych projektach. Użyłem również kontroli wersji w wielu projektach. Interesuje mnie współdziałanie tych dwóch narzędzi w typowym przepływie pracy, szczególnie jeśli chodzi o maksymę, aby utrzymywać małe zobowiązania. Oto kilka przykładów, które przychodzą na myśl:
Zaczynam nowy projekt i piszę prosty test, aby stworzyć klasę, która jeszcze nie istnieje. Czy powinienem wykonać test przed napisaniem klasy, nawet jeśli test się nawet nie skompiluje? A może powinienem usunąć minimalną ilość kodu potrzebną do skompilowania testu przed zatwierdzeniem?
Znajduję błąd i piszę test, aby go odtworzyć. Czy powinienem zatwierdzić test zakończony niepowodzeniem, czy wdrożyć poprawkę błędu, a następnie zatwierdzić?
Są to dwa przykłady, które przychodzą mi na myśl. Podaj dodatkowe przykłady w swojej odpowiedzi.
Edytować:
W obu przykładach założyłem, że zaraz po napisaniu testu napiszę kod, aby test przeszedł pomyślnie. Może się również pojawić inna sytuacja: pracuję nad projektem przy użyciu TDD przez kilka godzin bez zobowiązań. Kiedy w końcu podejmuję decyzje, chcę podzielić moją pracę na małe części. (Git sprawia, że jest to stosunkowo łatwe, nawet jeśli chcesz zatwierdzić tylko niektóre zmiany w jednym pliku).
Oznacza to, że moje pytanie dotyczy zarówno tego, co popełnić, jak i kiedy .
źródło
Nie.
Nie.
Mówisz tutaj o dwóch paradygmatach:
Moje zalecenie jest następujące: podążaj za kółkiem TDD, aż kod się skompiluje, twoje testy są zielone i masz coś do wniesienia do systemu. Dlatego powinieneś wyciąć swoje funkcje w pionie, np. W przypadku nowej maski interfejsu użytkownika nie twórz całego formularza i zatwierdzaj bez logiki biznesowej, ale raczej zaimplementuj jeden mały aspekt, ale w interfejsie użytkownika, a także logikę biznesową, a także w warstwie trwałości .
W przypadku dużej poprawki, zatwierdzaj po każdej poprawce (np. Refaktoryzacji), nawet jeśli błąd nie został jeszcze naprawiony. Testy powinny być zielone, a kod musi się jednak kompilować.
źródło
Na pewno zaczniesz od używania zdrowej kontroli źródła, takiej jak git.
Następnie możesz pracować tak, jak chcesz i zatwierdzać na każdym rogu - każdy krok lub podetap to uczciwa gra.
Następnie przed popchnięciem rzeczy zgniatasz całą pracę w jednym zatwierdzeniu. Lub para w punktach, w których wszystko jest zielone, a kompozycja ma sens. I popchnij te rozsądne zobowiązania. W przypadku wielu przypadków utwórz gałąź, którą scalisz z --no-ff.
Kontrola źródła nie jest systemem śledzenia pracy ani historykiem. Zatwierdzenia powinny wykazywać rozsądną spójną deltę, podczas gdy stan kasy powinien być co najmniej kompilowany. Pośrednie mogą być przez pewien czas zachowywane do celów przeglądu, ale gdy wszystko zostanie uznane za prawidłowe, pojedynczy zatwierdzenie na funkcję jest sprawiedliwy.
źródło
W moim rozumieniu świata zobowiązuje się zaznaczyć punkt, do którego może być pożądany powrót. Punkt, w którym test się nie udaje (ale się kompiluje) jest zdecydowanie jednym z takich punktów. Gdybym miał odejść w złym kierunku, próbując zdać test, chciałbym móc przywrócić kod z powrotem do punktu początkowego i spróbować ponownie; Nie mogę tego zrobić, jeśli się nie popełniłem.
źródło
Z rozgałęziającym się SCM (widziałem, że używasz Gita), powinieneś zatwierdzać, kiedy chcesz punkt zapasowy („Zepsułem coś; zresetuję działający katalog do ostatniego punktu kopii zapasowej”) lub gdy masz stabilną wersję. Jeśli masz stabilną wersję (wszystkie testy przeszły pomyślnie), powinieneś również rozważyć połączenie bieżącej gałęzi funkcji z główną gałęzią programistyczną.
Od ciebie (git daje ci elastyczność, którą możesz popełniać, kiedy tylko chcesz, bez wpływu na innych członków zespołu lub twoją zdolność do pracy nad różnymi funkcjami). Tylko upewnij się, że nie masz wielu niekompletnych (niedziałających) funkcji w tym samym oddziale w tym samym czasie (wtedy będą się wzajemnie blokować).
Zazwyczaj dokonuję dwóch zatwierdzeń, chyba że kod testowy jest naprawdę mały / trywialny do napisania.
To może być złe założenie. Jeśli pracujesz sam (osobisty projekt), nic nie stoi na przeszkodzie, abyś zawsze to robił. W jednym z moich najbardziej udanych projektów (w odniesieniu do utrzymywania wysokiej jakości kodu i TDD podczas opracowywania projektu) czasami definiowaliśmy testy na kilka tygodni przed ich wdrożeniem (tzn. Powiedzielibyśmy, że „test” test_FOO_z_null_first_parameter ”jest teraz definiowany jako pusta funkcja i tak to robimy). Następnie robiliśmy sprint (lub pół sprintu) czasami miesiąc lub więcej później, po prostu w celu zwiększenia zasięgu testu dla modułu.
Powiedziałbym zdecydowanie zobowiązać się do tworzenia punktów zapasowych . Działa to bardzo dobrze w przypadku testów eksploracyjnych („Dodam tylko kilka wydruków w całej bazie kodu, uruchomię je i
git reset --hard
usunę, gdy skończę) oraz do prototypowania.źródło
W mojej pracy, gdy tylko jest to możliwe, wykonuję niepewną pracę w osobistym oddziale kontroli źródła. Więc mogę spróbować, nie powiodło się, spróbuj ponownie, jeśli to konieczne, aż zadziała, i zatwierdzaj większy projekt tylko wtedy, gdy mam rzeczywisty działający kod.
Z perspektywy TDD pytanie „najpierw zameldujesz się w teście?” zależy całkowicie od kodu, nad którym pracujesz. Jeśli jest to nowy kod, niczego nie zameldujesz, dopóki nie będziesz mieć czegoś wartego zameldowania. Ale jeśli jest to błąd znaleziony w już skompilowanym lub wysłanym kodzie, warto sprawdzić w teście odtworzenia błędu BY BYŁO SAMODZIELNIE. Zwłaszcza jeśli jest to koniec dnia roboczego i opuścisz biuro przed naprawą kod.
(Oczywiście, jeśli Twój sklep ma zautomatyzowany proces kompilacji, który umiera, jeśli testy jednostkowe zakończą się niepowodzeniem, możesz nie chcieć sprawdzać testu zakończonego niepowodzeniem, dopóki nie naprawisz błędu. Ale to wydaje się dziwny sposób działania, ponieważ „znajdź oraz błędy w dokumentach ”i„ napraw błędy ”mogą być wykonywane przez dwa całkowicie różne zespoły).
źródło