Nie jestem pewien, w jaki sposób TDD, metodologia, obsługuje następujący przypadek. Załóżmy, że chcę zaimplementować algorytm scalania w Pythonie. Zaczynam od pisania
assert mergesort([]) === []
a test kończy się niepowodzeniem
Nazwa Błąd: nazwa „scalanie” nie jest zdefiniowana
Następnie dodaję
def mergesort(a):
return []
i mój test mija. Następnie dodaję
assert mergesort[5] == 5
i mój test kończy się niepowodzeniem
AssertionError
które przekazuję
def mergesort(a):
if not a:
return []
else:
return a
Następnie dodaję
assert mergesort([10, 30, 20]) == [10, 20, 30]
i teraz muszę spróbować to przekazać. „Znam” algorytm scalania, więc piszę:
def mergesort(a):
if not a:
return []
else:
left, right = a[:len(a)//2], a[len(a)//2:]
return merge(mergesort(left)), mergesort(right))
I to się nie udaje
NameError: nazwa „merge” nie jest zdefiniowana
Oto pytanie. Jak mogę uciec i zacząć wdrażać merge
za pomocą TDD? Wygląda na to, że nie mogę, bo mam ten „wiszący” niespełniony, nieudany test mergesort
, który nie przejdzie, dopóki się merge
nie skończy! Jeśli ten test się zawiesi, nigdy tak naprawdę nie będę mógł wykonywać TDD, ponieważ nie będę „zielony” podczas konstruowania iteracji TDD merge
.
Wygląda na to, że utknąłem w poniższych trzech brzydkich scenariuszach i chciałbym wiedzieć (1), który z nich preferuje społeczność TDD, lub (2) czy istnieje inne podejście, którego mi brakuje? Obejrzałem kilka instrukcji wujka Boba TDD i nie przypominam sobie, aby widziałem wcześniej taki przypadek!
Oto 3 przypadki:
- Zaimplementuj scalanie w innym katalogu z innym pakietem testowym.
- Nie martw się, że jesteś zielony podczas opracowywania funkcji pomocnika, po prostu ręcznie śledź, które testy naprawdę chcesz zdać.
- Skomentuj (GASP!) Lub usuń linie w
mergesort
tym połączeniumerge
; następnie pomerge
powrocie do pracy włóż je z powrotem.
Wszystko to wygląda dla mnie głupio (a może patrzę na to źle?). Czy ktoś zna preferowane podejście?
mergesort
, ponieważ jest to już bardzo dobrze zdefiniowany algorytm, ten proces wykrywania nie jest wymagany, a następnie staje się kwestią odwzorowania tego, co już wiesz, że jest projektem, na serię testów jednostkowych. Prawdopodobnie w teście najwyższego poziomu potwierdzono, że testowana metoda akceptuje nieposortowane zbiory i zwraca posortowane ...mergesort
. Jeśli szukasz „właściwego” sposobu na zrobienie tego, nie ma innego, niż być dokładnym w kwestii mapowaniamergesort
algorytmu na serię testów jednostkowych; tzn. powinny odzwierciedlać to, comergesort
faktycznie robi.mergesort
projekt wyłoni się naturalnie z refaktora czerwono-zielonego, nie stanie się to, dopóki nie pokierujesz procesem w oparciu o twoją wiedzęmergesort
.merge
musi być wynaleziony tylko na etapie „refaktoryzacji”. Jeśli zauważysz, żemerge
metoda ta może zostać wprowadzona do zaliczenia testumergesort
, najpierw wykonaj testy bezmerge
metody. Następnie refaktoryzuj swoją implementację, wprowadzającmerge
metodę.Odpowiedzi:
Oto kilka alternatywnych sposobów sprawdzenia dostępnych opcji. Ale najpierw zasady TDD od wuja Boba z naciskiem przeze mnie:
Tak więc jednym ze sposobów na odczytanie reguły nr 3 jest to, że potrzebujesz
merge
funkcji, aby przejść test, abyś mógł ją wdrożyć - ale tylko w najbardziej podstawowej formie.Lub, alternatywnie, zaczynasz od napisania operacji scalania w linii, a następnie przekształcasz ją w funkcję po uruchomieniu testu.
Inną interpretacją jest to, że piszesz w trybie scalania, wiesz, że będziesz potrzebować
merge
operacji (tzn. Nie jest to YAGNI, co właśnie „wystarczająca” reguła próbuje ograniczyć). Dlatego powinieneś zacząć od testów dla scalenia, a dopiero potem przejść do testów dla ogólnego sortowania.źródło
merge
jest to zaskakująco niechlujne, rozróżniające wielkość liter (a także przydatne jako samodzielne), pomysł zrobienia tego jako osobnej funkcji miał więcej sensu. Jednak styl robienia tego inline w swojej podstawowej formie, a następnie faktoryzowania go na etapie niebieskiego kapelusza, wydaje się być właściwy i bardzo tego szukałem.merge
operacji przed wykonaniem sortowania (a także na osobnym przetestowaniupartition
operacji). Wydaje mi się, że powstające korzyści płyną z powolnego dążenia do znanego celu. W przypadku połączenia nie sądzę, że celem jest sortowanie w ogóle (ponieważ wtedy skończysz na sortowaniu bąbelkowym). Znasz podstawowe operacje, więc pracujesz w kierunku tych operacji; ten rodzaj jest przeważnie przemyślany.merge
funkcjęmergesort
i kpij z jej zachowania. Następnie wróć imerge
najpierw wykonaj test. Delegaci są niesamowici ™.