Używałem unit testów w ograniczonym zakresie, do testowania jakchś tam algorytmów / ustrojstw, czy dobrze działają; nie używałem jeszcze TDD, nie mam jeszcze opinii na jego temat.
Dawałem radę używać (na małą skalę) testów bez podejścia "test first" - pisałem kod, stwierdzałem że jest skomplikowany i "niepewny", po czym pisałem do niego testy. Jeśli nie dawałem rady napisać testów, to go strukturyzowałem, by był rozbity na jakiegokolwiek rodzaju mniejsze jednostki (samo to nieraz znalazło mi buga :)) i testowałem je osobno, z powodzeniem.
(Przez "z powodzeniem" rozumiem, że moje buraki wyszły w testach, a nie po wdrożeniu.) Wyciągam stąd wniosek, że testy są bardzo fajne, ale TDD to niekoniecznie jedyna słuszna droga.
możesz napisać taki test:
Takie testy generalnie nic mi nie mówią. Widzę często takie pseudokodowe przykłady pisane przez entuzjastów, ale to jest straszne uproszczenie i myślę, że nie jestem jedynym "zielonym", któremu to niewiele mówi... :)
Myślę, że trzeba po prostu spróbować, by to polubić.
No dobra, jestem w stanie wyobrazić sobie, że mam jakąś klasę, która w reakcji na coś robi coś skomplikowanego, i akurat z góry wiem, że w konkretnym przypadku jej rezultat to ma być takie i takie wywołanie do obiektu XYZ. Wtedy mock mi pomoże napisać test.
Moje testy jednak zwykle wyglądały tak: Mam dane takie i takie, odpalam na nich algorytm i sprawdzam, czy po algorytmie dane zmieniły się w ten i ten sposób. Albo że nie zmieniły się wcale.
W takiej sytuacji mocki niewiele mi dadzą, bo nie wiem, jakie operacje mają być rezultatem akcji, wiem natomiast, jakie są oczekiwane dane.
Jeszcze trochę przeciwko TDD: Kod jestem w stanie przetestować lepiej, gdy go już napiszę. Jeśli zagadnienie uda mi się zaprogramować, to zapewne gdzieś po drodze udało mi się je zrozumieć :), zrobić sobie w głowie lub na kartce jakiś logiczny model, zidentyfikować różne dziwne edge cases bądź niespodziewane zawiłości. Jeśli mam kod, to znaczy, że zastanowiłem się i podjąłem decyzję, jak algo ma się zachowywać w tych zawiłościach.
Mogłem ofc się gdzieś pomylić, więc piszę testy. Ale teraz znam już konkretne zawiłości problemu (niekoniecznie zawiłości implementacji, ale właśnie samego problemu!) które muszę szczególnie przetestować. Nie znałem tych zawiłości przed stworzeniem kodu do testowania, więc testując później otrzymuję dokładniejsze testy.
Z tego powodu nie spieszę się z wypróbowaniem TDD.
Powyższego bardzo proszę nie mylić z "code tests against interface, not implementation" - to akurat znam i popieram :)
Mam natomiast nawyk pisania "pseudotestów" pseudokodem przed implementacją, bo to mi bardzo ułatwia wyobrażenie sobie, jak wygodnie lub niewygodnie się będzie z kodu korzystało.