Czy to ograniczenie rozwoju opartego na testach (i ogólnie Agile) jest praktycznie istotne?

30

W Test Driven Development (TDD) zaczynasz od rozwiązania nieoptymalnego, a następnie iteracyjnie produkujesz lepsze, dodając przypadki testowe i refaktoryzując. Kroki mają być małe, co oznacza, że ​​każde nowe rozwiązanie będzie w jakiś sposób znajdować się w sąsiedztwie poprzedniego.

Przypomina to matematyczne lokalne metody optymalizacji, takie jak opadanie gradientu lub wyszukiwanie lokalne. Dobrze znanym ograniczeniem takich metod jest to, że nie gwarantują one znalezienia globalnego optimum, ani nawet akceptowalnego lokalnego optimum. Jeśli punkt początkowy jest oddzielony od wszystkich akceptowalnych rozwiązań dużym regionem złych rozwiązań, nie można się tam dostać, a metoda zawiedzie.

Mówiąc dokładniej: myślę o scenariuszu, w którym zaimplementowałeś wiele przypadków testowych, a następnie stwierdziłem, że następny przypadek testowy wymagałby zupełnie innego podejścia. Będziesz musiał odrzucić swoją poprzednią pracę i zacząć od nowa.

Tę myśl można faktycznie zastosować do wszystkich zwinnych metod, które przebiegają małymi krokami, nie tylko do TDD. Czy ta proponowana analogia między TDD a lokalną optymalizacją ma jakieś poważne wady?

Frank Puffer
źródło
Czy masz na myśli pod-technikę TDD zwaną triangulacją ? Przez „akceptowalne rozwiązanie” masz na myśli prawidłowe, czy możliwe do utrzymania / eleganckie / czytelne?
guillaume31
6
Myślę, że to prawdziwy problem. Ponieważ to tylko moja opinia, nie napiszę odpowiedzi. Ale tak, ponieważ TDD jest reklamowane jako praktyka projektowa , wadą jest to, że może prowadzić do lokalnych maksimów lub braku rozwiązania. Powiedziałbym, że ogólnie TDD NIE nadaje się do projektowania algorytmicznego. Zobacz powiązane dyskusji na temat ograniczeń TDD: rozwiązywania sudoku z TDD , w którym Ron Jeffries sprawia osła z siebie podczas jazdy w kółko i „robi TDD”, podczas gdy Peter Norvig zapewnia rzeczywiste rozwiązanie według faktycznie wiedząc o Przedmiot,
Andres F.,
5
Innymi słowy, zaoferowałbym (miejmy nadzieję) niekontrowersyjne stwierdzenie, że TDD jest dobre do minimalizowania liczby klas, które piszesz w „znanych” problemach, a zatem do tworzenia czystszego i prostszego kodu, ale nie nadaje się do problemów algorytmicznych lub złożonych problemów, w których właściwie oglądanie dużego obrazu i posiadanie wiedzy specyficznej dla domeny jest bardziej przydatne niż pisanie fragmentarycznych testów i „odkrywanie” kodu, który musisz napisać.
Andres F.,
2
Problem istnieje, ale nie ogranicza się do TDD ani nawet Agile. Zmieniające się wymagania, które oznaczają, że projekt wcześniej napisanego oprogramowania musi się ciągle zmieniać.
RemcoGerlich,
@ guillaume31: Nie koniecznie triangulacja, ale dowolna technika wykorzystująca iteracje na poziomie kodu źródłowego. Przez akceptowalne rozwiązanie mam na myśli takie, które pomyślnie przeszło wszystkie testy i można je utrzymać dość dobrze.
Frank Puffer

Odpowiedzi:

8

Dobrze znanym ograniczeniem takich metod jest to, że nie gwarantują one znalezienia globalnego optimum, ani nawet akceptowalnego lokalnego optimum.

Aby twoje porównanie było bardziej adekwatne: w przypadku niektórych problemów iteracyjne algorytmy optymalizacji mogą generować dobre lokalne optymima, w niektórych innych przypadkach mogą zawieść.

Mam na myśli scenariusz, w którym zaimplementowałeś wiele przypadków testowych, a następnie stwierdziłem, że następny przypadek testowy wymagałby zupełnie innego podejścia. Będziesz musiał odrzucić swoją poprzednią pracę i zacząć od nowa.

Mogę sobie wyobrazić sytuację, w której może się to zdarzyć w rzeczywistości: kiedy wybierzesz niewłaściwą architekturę w taki sposób, że będziesz musiał odtworzyć wszystkie istniejące testy od nowa. Załóżmy, że zaczynasz wdrażać pierwsze 20 przypadków testowych w języku programowania X w systemie operacyjnym A. Niestety, wymaganie 21 obejmuje, że cały program musi działać w systemie operacyjnym B, gdzie X nie jest dostępny. Dlatego musisz wyrzucić większość swojej pracy i ponownie wdrożyć w języku Y. (Oczywiście nie wyrzuciłbyś kodu całkowicie, ale przeniósł go do nowego języka i systemu).

To uczy nas, nawet podczas korzystania z TDD, dobrym pomysłem jest wcześniejsze przeprowadzenie ogólnej analizy i projektu. Dotyczy to jednak każdego innego podejścia, więc nie uważam tego za nieodłączny problem TDD. W przypadku większości rzeczywistych zadań programistycznych możesz po prostu wybrać standardową architekturę (np. Język programowania X, system operacyjny Y, system bazy danych Z na sprzęcie XYZ) i możesz być stosunkowo pewny, że iteracyjna lub zwinna metodologia, taka jak TDD nie doprowadzi cię w ślepy zaułek.

Powołując się na Roberta Harveya: „Nie można wyhodować architektury na podstawie testów jednostkowych”. Lub pdr: „TDD nie tylko pomaga mi dojść do najlepszego ostatecznego projektu, ale pomaga mi dotrzeć tam przy mniejszej liczbie prób”.

Więc właściwie to co napisałeś

Jeśli punkt początkowy jest oddzielony od wszystkich akceptowalnych rozwiązań dużym regionem złych rozwiązań, nie można się tam dostać, a metoda zawiedzie.

może stać się prawdą - jeśli wybierzesz niewłaściwą architekturę, prawdopodobnie nie osiągniesz stamtąd wymaganego rozwiązania.

Z drugiej strony, kiedy wcześniej planujesz jakieś ogólne planowanie i wybierasz odpowiednią architekturę, korzystanie z TDD powinno być jak rozpoczęcie iteracyjnego algorytmu wyszukiwania w obszarze, w którym możesz oczekiwać osiągnięcia „globalnego maksimum” (lub przynajmniej wystarczająco dobrego maksimum ) w kilku cyklach.

Doktor Brown
źródło
20

Nie sądzę, że TDD ma problem lokalnych maksimów. Kod, który piszesz, może, jak zauważyłeś, ale właśnie dlatego refaktoryzacja (przepisywanie kodu bez zmiany funkcjonalności) jest na miejscu. Zasadniczo wraz ze wzrostem liczby testów można przepisać znaczną część modelu obiektowego, jeśli zachodzi taka potrzeba, zachowując niezmienione zachowanie dzięki testom. Testy stwierdzają niezmienne prawdy o twoim systemie, które dlatego muszą być ważne zarówno w lokalnych, jak i absolutnych maksimach.

Jeśli interesują Cię problemy związane z TDD, mogę wymienić trzy różne, o których często myślę:

  1. Kompletność Problem: ile testy są konieczne, aby całkowicie opisać system? Czy „kodowanie przykładowych przypadków” to kompletny sposób na opisanie systemu?

  2. Hartowania problemem: cokolwiek testuje interfejs, musi mieć niezmienną interfejs. Pamiętajcie, że testy reprezentują niezmienne prawdy . Niestety, te prawdy w ogóle nie są znane w przypadku większości kodu, który piszemy, w najlepszym wypadku tylko w przypadku zewnętrznych obiektów.

  3. Uszkodzenie testu problemem: w celu dokonania twierdzeń sprawdzalne, możemy trzeba pisać kodu nieoptymalne (mniej wydajnych, na przykład). Jak piszemy testy, aby kod był tak dobry, jak to tylko możliwe?


Edytowane w celu zaadresowania komentarza: oto przykład przekroczenia lokalnego maksimum dla funkcji „podwójnej” poprzez refaktoryzację

Test 1: gdy wartość wejściowa wynosi 0, zwróć zero

Realizacja:

function double(x) {
  return 0; // simplest possible code that passes tests
}

Refaktoryzacja: nie jest wymagana

Test 2: gdy wejście to 1, zwróć 2

Realizacja:

function double(x) {
  return x==0?0:2; // local maximum
}

Refaktoryzacja: nie jest wymagana

Test 3: gdy wejście to 2, zwróć 4

Realizacja:

function double(x) {
  return x==0?0:x==2?4:2; // needs refactoring
}

Refaktoryzacja:

function double(x) {
  return x*2; // new maximum
}
Sklivvz
źródło
1
Doświadczyłem jednak tego, że mój pierwszy projekt działał tylko w niektórych prostych przypadkach, a później zdałem sobie sprawę, że potrzebuję bardziej ogólnego rozwiązania. Opracowanie bardziej ogólnego rozwiązania wymagało więcej testów, podczas gdy oryginalne testy dla specjalnych przypadków już nie będą działać. Zaakceptowałem (tymczasowo) usunięcie tych testów podczas opracowywania bardziej ogólnego rozwiązania, dodając je z powrotem, gdy czas będzie gotowy.
5gon12eder
3
Nie jestem przekonany, czy refaktoryzacja jest sposobem na uogólnienie kodu (oczywiście poza sztuczną przestrzenią „wzorców projektowych”, oczywiście) lub uniknięcie lokalnych maksimów. Refaktoryzacja uporządkuje kod, ale nie pomoże ci znaleźć lepszego rozwiązania.
Andres F.,
2
@Sklivvz Zrozumiałem, ale nie sądzę, że działa w ten sposób poza przykładami zabawek, takimi jak te, które opublikowałeś. Pomogło ci to również nazwać twoją funkcję „podwójną”; w sposób, w jaki znasz już odpowiedź. TDD zdecydowanie pomaga, gdy mniej więcej znasz odpowiedź, ale chcesz napisać ją „czysto”. Nie pomogłoby to w odkrywaniu algorytmów lub pisaniu naprawdę skomplikowanego kodu. Właśnie dlatego Ron Jeffries nie rozwiązał Sudoku w ten sposób; nie możesz zaimplementować nieznanego algorytmu przez TDD, usuwając go z niejasności.
Andres F.,
1
@ VaughnCato Ok, teraz jestem w stanie albo ci zaufać, albo być sceptycznym (co byłoby niegrzeczne, więc nie róbmy tego). Powiedzmy, z mojego doświadczenia, że ​​to nie działa tak jak mówisz. Nigdy nie widziałem, aby dość skomplikowany algorytm ewoluował z TDD. Może moje doświadczenie jest zbyt ograniczone :)
Andres F.
2
@Sklivvz „Tak długo, jak potrafisz napisać odpowiednie testy”, właśnie o to chodzi: brzmi to jak proszenie mnie o pytanie. Mówię tylko, że często nie możesz . Myślenie o algorytmie lub rozwiązaniu nie jest łatwiejsze, pisząc najpierw testy . Najpierw musisz spojrzeć na całe zdjęcie . Próbowanie scenariuszy jest oczywiście konieczne, ale uwaga: TDD nie polega na pisaniu scenariuszy: TDD polega na testowaniu projektu ! Nie możesz prowadzić projektu solvera Sudoku (lub nowego solvera dla innej gry), pisząc najpierw testy. Jako dowód anegdotywny (co nie wystarczy): Jeffries nie mógł.
Andres F.,
13

To, co opisujesz matematycznie, to to, co nazywamy malowaniem się w kącie. Zjawisko to nie wyklucza wyłącznie TDD. W wodospadzie możesz zbierać i przesypywać wymagania przez miesiące, mając nadzieję, że zobaczysz globalne maksimum tylko po to, aby się tam dostać i zdać sobie sprawę, że jest lepszy pomysł tylko na następną górkę.

Różnica polega na zwinnym środowisku, w którym nigdy nie spodziewałeś się, że będziesz idealny w tym momencie, więc jesteś więcej niż gotowy, by rzucić stary pomysł i przejść do nowego.

Bardziej specyficzne dla TDD jest technika, aby temu zapobiec, gdy dodajesz funkcje w TDD. To Przesłanka Priorytetowa Transformacji . Tam, gdzie TDD ma formalny sposób na refaktoryzację, jest to formalny sposób dodawania funkcji.

candied_orange
źródło
13

W swojej odpowiedzi @Sklivvz przekonująco argumentował, że problem nie istnieje.

Chcę argumentować, że to nie ma znaczenia: podstawową przesłanką (i raison d'être) iteracyjnych metodologii ogólnie i Agile, a zwłaszcza TDD w szczególności, jest to, że nie tylko globalne optimum, ale także lokalne optymalizacje nie są znany Innymi słowy: nawet jeśli był to problem, nie ma mowy o robieniu tego iteracyjnie. Zakładając, że akceptujesz podstawowe założenie.

Jörg W Mittag
źródło
8

Czy praktyki TDD i Agile mogą zapewnić optymalne rozwiązanie? (A może nawet „dobre” rozwiązanie?)

Nie dokładnie. Ale to nie jest ich cel.

Metody te zapewniają po prostu „bezpieczne przejście” z jednego stanu do drugiego, potwierdzając, że zmiany są czasochłonne, trudne i ryzykowne. Obie praktyki mają na celu zapewnienie, że aplikacja i kod są wykonalne i udowodniono, że spełniają wymagania szybciej i bardziej regularnie.

... [TDD] jest przeciwny opracowywaniu oprogramowania, które pozwala na dodawanie oprogramowania, które nie spełnia wymagań ... Kent Beck, któremu przypisuje się opracowanie lub „ponowne odkrycie” tej techniki, stwierdził w 2003 r., Że TDD zachęca do prostego projektuje i budzi zaufanie. ( Wikipedia )

TDD koncentruje się na zapewnieniu, że każda „część” kodu spełnia wymagania. W szczególności pomaga upewnić się, że kod spełnia wcześniej istniejące wymagania, a nie pozwala, aby wymagania były sterowane przez słabe kodowanie. Ale nie obiecuje, że wdrożenie jest w jakikolwiek sposób „optymalne”.

Jeśli chodzi o procesy zwinne:

Działające oprogramowanie jest podstawową miarą postępu ... Pod koniec każdej iteracji interesariusze i przedstawiciel klienta przeglądają postępy i ponownie oceniają priorytety w celu zoptymalizowania zwrotu z inwestycji ( Wikipedia )

Zwinność nie szuka optymalnego rozwiązania ; tylko działające rozwiązanie - z myślą o optymalizacji ROI . Obiecuje działające rozwiązanie wcześniej niż później ; nie „optymalny”.

Ale to OK, ponieważ pytanie jest złe.

Optymalne w tworzeniu oprogramowania są rozmyte, ruchome cele. Wymagania są zwykle zmienne i pełne tajemnic, które pojawiają się tylko, ku twojemu zawstydzeniu, w sali konferencyjnej pełnej szefów twojego szefa. „Wewnętrzna dobroć” architektury i kodowania rozwiązania jest oceniana na podstawie podzielonych i subiektywnych opinii twoich rówieśników i opinii twojego kierowniczego zwierzchnika - z których żaden tak naprawdę nie mógł wiedzieć o dobrym oprogramowaniu.

W każdym razie, TDD i Agile praktyki uznają trudności i próby w celu optymalizacji dla dwóch rzeczy, które obiektywne i mierzalne: . Robocza V nie pracujący i prędzej v później..

I nawet jeśli mamy „pracować” i „wcześniej” jako obiektywne wskaźniki, twoja zdolność do ich optymalizacji zależy przede wszystkim od umiejętności i doświadczenia zespołu.


Do rzeczy, które można interpretować, gdy wysiłki dają optymalne rozwiązania, należą:

itp..

To, czy każda z tych rzeczy faktycznie zapewnia optymalne rozwiązania, byłoby kolejnym wielkim pytaniem!

svidgen
źródło
1
To prawda, ale nie napisałem, że celem TDD lub innej metody opracowywania oprogramowania jest optymalne rozwiązanie w sensie globalnego optimum. Moją jedyną obawą jest to, że metodologie oparte na małych iteracjach na poziomie kodu źródłowego mogą w ogóle nie znaleźć żadnego akceptowalnego (wystarczająco dobrego) rozwiązania
Frank Puffer
@Frank Moja odpowiedź ma objąć zarówno lokalne, jak i globalne wartości optymalne. A odpowiedź brzmi tak: „Nie, nie po to są te strategie - mają na celu poprawę ROI i ograniczenie ryzyka”. ... czy jakoś tak. Po części wynika to z odpowiedzi Jörga: „optimum” porusza się. ... zrobiłbym nawet krok dalej; nie tylko poruszają się cele, ale nie są całkowicie obiektywne ani mierzalne.
svidgen
@FrankPuffer Może warto uzupełnić. Ale podstawową kwestią jest to, czy pytasz, czy te dwie rzeczy osiągają coś, czego wcale nie zaprojektowali lub nie zamierzali osiągnąć. Co więcej, pytasz, czy mogą osiągnąć coś, czego nawet nie da się zmierzyć ani zweryfikować.
svidgen
@FrankPuffer Bah. Próbowałem zaktualizować swoją odpowiedź, aby powiedzieć to lepiej. Nie jestem pewien, czy zrobiłem to lepiej czy gorzej! ... Ale muszę zejść z SE.SE i wrócić do pracy.
svidgen
Ta odpowiedź jest dobra, ale mam z nią problem (podobnie jak w przypadku innych odpowiedzi), że „ograniczenie ryzyka i poprawa ROI” nie zawsze są najlepszymi celami. W rzeczywistości same nie są prawdziwymi celami. Kiedy potrzebujesz czegoś do pracy, ograniczanie ryzyka nie będzie go zmniejszać. Czasami względnie niedokierowane małe kroki, jak w TDD, nie działają - zminimalizujesz ryzyko w porządku, ale w końcu nie dotrzesz do niczego przydatnego.
Andres F.,
4

Jedną z rzeczy, których do tej pory nikt nie dodał, jest to, że opisywany „Rozwój TDD” jest bardzo abstrakcyjny i nierealny. Może tak być w przypadku aplikacji matematycznej, w której optymalizujesz algorytm, ale nie dzieje się tak często w aplikacjach biznesowych, nad którymi pracuje większość programistów.

W prawdziwym świecie twoje testy w zasadzie sprawdzają i weryfikują reguły biznesowe:

Na przykład - jeśli klientem jest 30-letni niepalący z żoną i dwójką dzieci, kategorią premium jest „x” itp.

Nie będziesz iteracyjnie zmieniać silnika obliczeń premium, dopóki nie będzie on poprawny przez bardzo długi czas - i prawie na pewno nie, dopóki aplikacja będzie uruchomiona;).

To, co faktycznie stworzyłeś, to siatka bezpieczeństwa, dzięki której po dodaniu nowej metody obliczeń dla określonej kategorii klientów wszystkie stare reguły nie łamią się nagle i udzielają złej odpowiedzi. Siatka bezpieczeństwa jest jeszcze bardziej przydatna, jeśli pierwszym krokiem debugowania jest utworzenie testu (lub serii testów), który odtwarza błąd przed napisaniem kodu w celu naprawienia błędu. Następnie, rok później, jeśli ktoś przypadkowo odtworzy pierwotny błąd, test jednostkowy psuje się, zanim kod zostanie nawet wpisany. Tak, jedną rzeczą, na którą pozwala TDD, jest to, że możesz teraz robić duże refaktoryzacje i porządkować rzeczy z pewnością ale to nie powinna być ogromna część twojej pracy.

Mcottle
źródło
1
Po pierwsze, kiedy czytam twoją odpowiedź, pomyślałem „tak, to jest sedno sprawy”. Ale po ponownym przemyśleniu pytania pomyślałem, że niekoniecznie musi być ono tak abstrakcyjne lub nierealne. Jeśli ktoś na ślepo wybiera całkowicie niewłaściwą architekturę, TDD nie rozwiąże tego, nie po 1000 iteracjach.
Doc Brown
@Doc Brown zgodził się, że nie rozwiąże tego problemu. Ale da ci zestaw testów, które sprawdzają wszystkie założenia i reguły biznesowe, dzięki czemu możesz iteracyjnie ulepszać architekturę. Architektura tak bardzo, że do poprawienia wymaga gruntownego przepisania, jest bardzo rzadka (mam nadzieję), a nawet w tym ekstremalnym przypadku testy jednostek reguł biznesowych byłyby dobrym punktem wyjścia.
mcottle,
Kiedy mówię „zła architektura”, mam na myśli przypadki, w których należy wyrzucić istniejący zestaw testów. Czy przeczytałeś moją odpowiedź?
Doc Brown
@DocBrown - Tak, zrobiłem. Jeśli miałeś na myśli „złą architekturę”, oznaczającą „zmień cały pakiet testowy”, być może powinieneś to powiedzieć. Zmiana architektury nie oznacza, że ​​musisz zniszczyć wszystkie testy, jeśli są one oparte na regułach biznesowych. Prawdopodobnie będziesz musiał zmienić je wszystkie, aby obsługiwać wszelkie nowe interfejsy, które utworzysz, a nawet całkowicie je ponownie napisać, ale Reguły biznesowe nie zostaną zastąpione zmianami technicznymi, więc testy pozostaną. Z pewnością inwestowanie w testy jednostkowe nie powinno być unieważniane przez mało prawdopodobną możliwość całkowitego
udoskonalenia
jasne, nawet jeśli trzeba przepisać każdy test w nowym języku programowania, nie trzeba wyrzucać wszystkiego, przynajmniej można przenieść istniejącą logikę. I zgadzam się z tobą w 100% w przypadku dużych rzeczywistych projektów, założenia w pytaniu są dość nierealne.
Doc Brown
3

Nie sądzę, żeby to przeszkadzało. Większość zespołów nie ma nikogo, kto byłby w stanie wymyślić optymalne rozwiązanie, nawet jeśli zapisałeś to na ich tablicy. TDD / Agile nie będzie im przeszkadzać.

Wiele projektów nie wymaga optymalnych rozwiązań, a te, które wymagają, będą poświęcać niezbędny czas, energię i skupić się na tym obszarze. Jak wszystko, co zwykle budujemy, po pierwsze, aby działało. Więc zrób to szybko. Możesz to zrobić za pomocą jakiegoś prototypu, jeśli wydajność jest tak ważna, a następnie odbudować całość dzięki mądrości zdobytej podczas wielu iteracji.

Mam na myśli scenariusz, w którym zaimplementowałeś wiele przypadków testowych, a następnie stwierdziłem, że następny przypadek testowy wymagałby zupełnie innego podejścia. Będziesz musiał odrzucić swoją poprzednią pracę i zacząć od nowa.

Może się to zdarzyć, ale bardziej prawdopodobne jest obawa przed zmianą skomplikowanych części aplikacji. Brak testów może zwiększyć poczucie strachu w tym obszarze. Jedną z zalet TDD i posiadania zestawu testów jest to, że zbudowałeś ten system z myślą, że trzeba będzie go zmienić. Gdy wymyślisz to monolityczne zoptymalizowane rozwiązanie od samego początku, jego zmiana może być bardzo trudna.

Umieść to również w kontekście obaw związanych z niedostateczną optymalizacją, a nie możesz nie poświęcić czasu na optymalizację rzeczy, których nie powinieneś mieć, i tworzenie nieelastycznych rozwiązań, ponieważ byłeś tak bardzo skoncentrowany na ich wydajności.

JeffO
źródło
0

Wprowadzanie koncepcji matematycznych takich jak „lokalne maksimum” do projektowania oprogramowania może być mylące. Korzystanie z takich terminów sprawia, że ​​tworzenie oprogramowania wydaje się o wiele bardziej kwantyfikowalne i naukowe niż w rzeczywistości. Nawet jeśli istnieje „optymalny” kod, nie mamy możliwości jego zmierzenia, a zatem nie wiemy, czy go osiągnęliśmy.

Zwinny ruch był naprawdę reakcją na przekonanie, że rozwój oprogramowania można planować i przewidywać metodami matematycznymi. Na lepsze lub gorsze, tworzenie oprogramowania bardziej przypomina rzemiosło niż naukę.

JacquesB
źródło
Ale czy to była zbyt silna reakcja? Z pewnością pomaga w wielu przypadkach, w których ścisłe planowanie z góry okazało się niewygodne i kosztowne. Jednak niektóre problemy z oprogramowaniem należy traktować jako problem matematyczny i przy projektowaniu z góry. Nie możesz ich TDD. Możesz TDD interfejsu użytkownika i ogólnego projektu Photoshopa, ale nie możesz TDD jego algorytmów. Nie są to trywialne przykłady, takie jak wyprowadzanie „sumy”, „podwójnej” lub „pow” w typowych przykładach TDD [1]). Prawdopodobnie nie możesz drażnić się z nowym filtrem obrazu podczas pisania scenariuszy testowych; absolutnie musisz usiąść, pisać i rozumieć formuły.
Andres F.,
2
[1] W rzeczywistości jestem całkiem pewien fibonacci, że widziałem to jako przykład / samouczek TDD, to mniej więcej kłamstwo. Jestem skłonny założyć się, że nikt nigdy nie „odkrył” Fibonacciego lub podobnej serii przez TDD. Wszyscy zaczynają od znajomości fibonacciego, który oszukuje. Jeśli spróbujesz to odkryć przez TDD'ing, prawdopodobnie dojdziesz do ślepego zaułka, o który prosi OP: nigdy nie będziesz w stanie uogólnić serii po prostu pisząc więcej testów i refaktoryzacji - musisz zastosować matematykę rozumowanie!
Andres F.,
Dwie uwagi: (1) Masz rację, że może to być mylące. Ale nie napisałem, że TDD jest tym samym co optymalizacja matematyczna. Po prostu użyłem go jako analogii lub modelu. Wierzę, że matematyka może (i powinna) być stosowana do prawie wszystkiego, o ile zdajesz sobie sprawę z różnic między modelem a rzeczywistością. (2) Nauka (praca naukowa) jest zwykle jeszcze mniej przewidywalna niż tworzenie oprogramowania. Powiedziałbym nawet, że inżynieria oprogramowania bardziej przypomina pracę naukową niż rzemiosło. Rzemiosło zwykle wymaga znacznie więcej rutynowej pracy.
Frank Puffer,
@AndresF .: TDD nie oznacza, że ​​nie musisz myśleć ani projektować. Oznacza to po prostu napisanie testu przed napisaniem implementacji. Możesz to zrobić za pomocą algorytmów.
JacquesB
@FrankPuffer: OK, więc jaką mierzalną wartość ma „lokalne optimum” w rozwoju oprogramowania?
JacquesB