TDD, czyli programowanie sterowane testami jest jedną z tzw. zwinnych praktyk programowania. Zazwyczaj, niesłusznie, ogranicza się testy do testów jednostkowych. Samo TDD nie definiuje z jakimi dokładnie testami pracujemy. Jednakże testy jednostkowe jako najprostsze do ogarnięcia są też uznawane za kwintesencję TDD.

Dziś chciałbym przedstawić wam pewien sposób pracy, który pozwala na lepsze przyswojenie sobie praktyki „test first”. Inaczej mówiąc jeżeli problemem jest dla ciebie pisanie najpierw testu potem kodu, to tu znajdziesz pomoc. Choć za rezultaty nie ręczę 🙂

Moja smutna historia

Gdy po raz pierwszy przedstawiono mi ideę TDD wydawał mi się banalnie prosta. Piszemy test, uruchamiamy go i mamy czerwono. Następnie piszemy kod do momentu, aż będzie zielono. Wtedy też piszemy kolejny test, który się zaczerwieni i dopisujemy kolejny „zieleniący” kawałek kodu. Zapętlamy. Po kilku obrotach dokładamy cegiełkę refaktoryzacji, by uprzątnąć plac budowy. Proste? Przynajmniej jak się to czyta. Takie podejście zwane „test first” jest bardzo dobre, bo pozwala na bieżąco kontrolować kod i wychwytywać co grubsze babole.

Problem z jakim się zetknąłem był jednak dość specyficzny, acz popularny. Java jako język statycznie typowany słabo znosi brak metod. W efekcie bardzo szybko zamiast pisania testu i skupieni się na tym co chcę wyrazić zaczynałem pisać metody. Jak zacząłem pisać metody, to wpadałem we „flow”, który powodował, że zaniedbywałem testy. Jak zaniedbałem testy, to później je dopisywałem tak by były ok. Z test first (TF) robiło się code first (CF). Najprostszym i najszybszym rozwiązaniem jest pisanie w parach. Dwa samce/samice zamknięte na małej przestrzeni (biurko) i zmuszone do współdzielenia zasobów (klawiatura) zaczną rywalizować. Jako, że jesteśmy ludźmi cywilizowanymi i do tego programistami, to nasza rywalizacja przeniesie się na poziom porównywania naszych umiejętności. W takim układzie oba samce/samice będą na wzajem się pilnować by robić dobrze kodowi, a każda okazja do wbicia szpili będzie bezwzględnie wykorzystywana. Jeżeli zamienimy parę na różnopłciową to zadziała mechanizm „jak ci mała pokażę jak to się robi” kontra „nie jestem taka durna chuju”. Efekt będzie taki sam.

Podejście kodowania w parach sprawdziłem w różnych konfiguracjach. Zazwyczaj działało. Jedynym warunkiem jest brak dużej różnicy umiejętności. W takim wypadku ze współpracy idziemy w kierunku nauczania, a to choć wartościowe dla obu stron, nie rozwiązuje problemu.

Co w przypadku gdy nie mamy możliwości kodowania w parze? Jak w tedy walczyć z problemem odchodzenia od test first? Po kilku latach zmagań z tym problemem mogę powiedzieć, że mam całkiem dobre rozwiązanie. W dodatku kompiluje się, działa i ma testy. Sprawdziłem je też w sytuacjach kryzysowych i wiem, że nawet osoba, która nie ma dużej wprawy w pisaniu testów spokojnie je będzie wstanie wdrożyć. Kluczem do sukcesu jest odpowiednia konfiguracja IDE.

Kod i testy – wygląd

Można powiedzieć, że jeżeli dobrze znamy swoje IDE to potrafimy od ręki rozwiązać połowę problemów, z którymi będziemy się mierzyć. W moim podejściu kluczem do sukcesu jest znajomość IDE i odpowiednie jego używanie. Gdy zacząłem analizować problem „dryfu z TF do CF”, to jedną z pierwszych rzeczy jakie zauważyłem była irytacja wynikająca z przeskakiwania pomiędzy testem, a kodem. Na początek należy zatem ograniczyć ilość tego typu skoków. Jednak same skoki nie są tak irytujące jak „wtrącenia”, czyli przejście do pliku, którego aktualnie nie używamy.

Po pierwsze zmniejsz masę

Jak piszesz kod i testy jednostkowe do niego (upraszczam, ale później uogólnimy), to zamknij wszystkie inne pliki w IDE. Jeżeli pozwala, to zamknij też inne okna. Niech nie będzie widoczne nic poza kodem. IntelliJ Idea i pochodne posiadają tryb pełnoekranowy:

TDD1

oraz „distraction free mode” (DFM):

TDD2

Jeżeli masz za małe literki powiększ je albo zamiast DFM użyj trybu prezentacji. Dzięki temu pozbędziesz się rozpraszaczy. Wadą DFM jest utrata powiększenia liter po zmianie pliku. Dlatego też osobiście preferuję tryb pełnoekranowy.

Po drugie poznaj IDE

W praktyce poznaj skróty klawiaturowe, które służą do nawigowania pomiędzy kodem i testami:

  • ctrl+shift+t – tworzy nową klasę testową albo pozwala przejść do testu z kodu. Jeżeli jesteś w klasie testowej i masz co najmniej jedną metodę testową to skacze do klasy testowanej.
  • ctrl+e – działa podobnie do alt+tab, ale nawiguje pomiędzy ostatnio otwartymi plikami.
Po trzecie wykorzystaj monitor(y)

IntelliJ Idea posiada takie magiczne coś jak podział ekranu pomiędzy dwa edytory. Najprościej zrobić to klikając PPM na tytule zakładki i następnie wybrać opcję Split Vertically:

TDD3

W ten sposób na jednym ekranie mamy na raz i testy i nasz kod. Ogranicza to uciążliwość skoków pomiędzy plikami. Jednocześnie lepiej wykorzystujemy powierzchnię ekranu. Dodatkowo „jakoś samo się tak dzieje”, że dbamy o to by nasze linie były krótkie. U mnie limit to 120 znaków z czego widoczne jest około 110. Standardem jest 80 znaków, ale już nie bądźmy tacy ortodoksyjni.

Kod i testy – działanie

Kolejna rzecz to uruchamianie testów. Jest to zazwyczaj możliwe jednym przyciskiem. Jeszcze lepiej jeżeli można to zrobić jednym skrótem klawiaturowym:

  • ctrl+shift+F10 – uruchamia testy z bieżącego pliku. Poprzedzony ctrl+shift+t w pliku z kodem pozwala na uruchomienie testów z poziomu kodu.
  • ctrl+F5 – powtarza ostatnie uruchomienie. Przydatne do powtórnego uruchamiania testów.

Jak już uruchomimy testy to nie zamykamy okna z wynikami. To ważne ponieważ, znowu, ogranicza to ilość gwałtownych zmian w wyglądzie obszaru roboczego. Ekran można jeszcze oczyścić w menu View (alt+v) wyłączając wszystkie paski narzędzi, nawigacji czy statusu (ten sobie zostawiam, bo lubię patrzeć na zajęty RAM):

TDD4

Podsumowanie

Na początku każdej większej zmiany najbardziej przeszkadzają drobnostki. Jesteśmy gotowi na „duże” problemy, ale to duperele nas wkurzają i zniechęcają. Dlatego też warto zacząć od eliminacji choć części z nich. Takie małe sukcesy pomagają nam też w kontynuacji pracy, bo czujemy, że coś zrobiliśmy.