• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

TDD w praktyce

VPS Starter Arubacloud
+4 głosów
647 wizyt
pytanie zadane 19 maja 2015 w Rozwój zawodowy, nauka, praca przez MrWeb Stary wyjadacz (10,200 p.)
Cześć,

Jestem w połowie książki "Mistrz czystego kodu. Kodeks postępowania profesjonalnych programistów" i bardzo często wspominany jest termin TDD (Test Driven Development) lecz nigdzie nie jest wspomniane jak tego używać w praktyce.

Wiem, że cały trick polega na trzech zasadach i testach jednostkowych. W teorii brzmi to świetnie (szczególnie jeśli chodzi o ilość zlikwidowanych błędów w kodzie) ale nie wiem jak tego użyć w rzeczywistym pisaniu funkcji...

Ktoś ma może jakieś poradniki / przykłady ?

1 odpowiedź

+4 głosów
odpowiedź 19 maja 2015 przez Comandeer Guru (599,730 p.)
wybrane 19 maja 2015 przez MrWeb
 
Najlepsza

Może rzucę coś od siebie, z właśnego nie-tak-duźego doświadczenia…

TDD to przede wszystkim zmiana w myśleniu. Najtrudniejsze w całym tym procesie jest zrozumienie samej idei - a zatem przejścia od klupania kodu do projektowania go w trakcie pisania testów.

Weźmy se prostą klasę reprezentującą Test (https://github.com/Auditr/Test/). Na początek proste założenia:

  • Klasa ta ma reprezentować zbiór czynności, które są wykonywane na zadanej stronie WWW
  • Strona ma być oceniona pod względem tego czy czynności te udało się wykonać poprawnie
  • User ma dostać wynik punktowy

Założenia proste, ale już nam uzmysławiają mniej więcej jak musimy to pisać w taki sposób, żeby kod był jak najlepiej pokryty testami. Sam wygląd API również będziemy ustalać pisząc testy (implementacja jest tylko wypełnieniem założeń narzuconych przez testy!):

  • Całość systemu podzielimy na 3 części: klasę reprezentującą stronę, klasę reprezentującą sam test i klasę reprezentującą wynik. Dzięki takiemu podziałowi każdy element będzie można przetestować oddzielnie, bez zastanawiania się czy przypadkiem zależności pomiędzy nimi (lub - w przypadku strony - połączenie sieciowe) nie wpłynęły na wynik. Stronę będziemy zatem mockować, żeby zachowywała się w ściśle określony sposób i tym samym test produkował przewidywalne wyniki
  • Zastanawiamy się jakie metody będą nam potrzebne i co powinny zwracać. Jak już to wymyślimy, piszemy prosty test sprawdzający daną rzecz, np. wiadomo, że test musi się wykonać (Test::run()) zanim będzie możliwość pobrania wyniku (Test::getResult()). Tym samym należy sprawdzić czy rzeczywiście tak jest (czyli inaczej mówiąc: czy klasa Test rzuci wyjątek jeśli najpierw wywołamy Test::getResult() a dopiero potem Test::run()). W podobny sposób możemy potestować pozostałe części naszego kodu
  • Kiedy już napiszemy sobie ładny projekt naszego API w postaci testów, warto sprawdzić czy nasz kod je oblewa (hint: nasz kod nie istnieje, więc oblewa ;)). Jeśli oblewanie działa, czas zacząć pisać kod tak, żeby te testy zdawał (czyli wyposażmy naszą metodę Test::getResult() w warunek, który sprawdzi czy wcześniej zostało odpalone Test::run() i w razie potrzeby walnie wyjątkiem)
  • Trzeba będzie kiedyś dodać nową funkcjonalność? Żaden problem - dodamy ją w testach, a później dopiszemy kod pod to ;)

Przykładowe test do klasy Test można znaleźć tutaj: https://github.com/Auditr/Test/blob/master/tests/TestTest.php → nie twierdzę, że są one idealne, ale zapewniają, że kod działa tak, jak powinien.

 

komentarz 19 maja 2015 przez MrWeb Stary wyjadacz (10,200 p.)
edycja 19 maja 2015 przez MrWeb

Załóżmy, że chcę napisać super silnik do gier z użyciem TDD.

  •  Biorę kartkę papieru i zastanawiam się nad głównym zadaniem silnika
  • Dzielę jego zachowania w grupy z których mogę napisać klasy (Wszystko co związane z fizyką/przemieszczaniem do np PhysicsEngine a wszystko co związane z pojawieniem się na ekranie do np RenderEngine)
  • Dzielę każdą z klas na poszczególne funkcje oraz zadania które miałaby spełniać (tworzę API klasy)
  • =========================================
  • [Załóżmy że mam w tym momencie rozwiązany problem chierarchii i zależności klas, rozpisane API każdej z z klas i napisane puste prototypy funkcji tych klas]
  • =========================================
  • kompiluję i nie zdaję testów
  • uzupełniam pojedyńczą funkcję
  • testuję wszystko tak jak wcześniej i też nie zdaję za wyjątkiem tej pierwszej funkcji
  • poprawiam kolejną jedną funkcję
  • powtarzam test
  • =========================================
  • [i tak w kółko aż do całkowitego przejścia testu]
  • =========================================
  • dalej co? rozwijam faktyczne api?

 

Edit: dodałem formatowanie bo nie dało się tego czytać.

komentarz 19 maja 2015 przez Comandeer Guru (599,730 p.)
Nie musisz poprawiać funkcji po jednej. Kluczowy jest tutaj fakt, że projekt API to tak naprawdę testy. Jeśli kod przechodzi testy, to znaczy, że jest zgodny z API i działa tak, jak założyłeś.

Rozwijanie API to tak naprawdę zagwarantowanie, że kod przejdzie testy, bo całe API masz na nie rozpisane.
komentarz 19 maja 2015 przez MrWeb Stary wyjadacz (10,200 p.)
edycja 19 maja 2015 przez MrWeb
1) Test wykonuję ja poprzez uruchomienie builda i ręczne sprawdzenie czy działa tak jak zakładałem czy piszę w kodzie faktyczny test (np warunki przy alokacji pamięci, asserty, breakpointy, zapis informacji do pliku z logami)

2)Te testy się usuwa po sprawdzeniu poprawności kodu ? (W kodzie z linku podanego wyżej nie ma nic ciekawego jeśli chodzi o budowę funkcji itd, większość z nich po prostu zwraca różne wartości...)
komentarz 19 maja 2015 przez Comandeer Guru (599,730 p.)
Testy to asserty - nie mają nic wspólnego z kompilacją.

Test, w którym sprawdzasz coś samemu to nie są już testy jednostkowe, bo sprawdzasz całą aplikację naraz, nie jej poszczególne części osobno. IMO nazwałbym to "interaktywnymi testami integracyjnymi" ;) http://dariuszwozniak.net/2013/05/28/kurs-tdd-czesc-2-testy-jednostkowe-a-testy-integracyjne/

Polecam np sprawdzić jak wygląda testowanie w Go (to w sumie jedyny kompilowany język, jaki choć trochę kojarzę na chwilę obecną…): http://www.binpress.com/tutorial/getting-started-with-go-and-test-driven-development/160

Co do tego czy ktoś używa - testy z założenia mają zapewniać wyższą jakość kodu, więc poprawna odpowiedź brzmi: "każdy dobry programista" ;) Nie, testów się nie usuwa - są integralną częścią projektu i w wielu przypadkach służą jako jego dokumentacja dla innych programistów (bo pokazują jak działają główne elementy systemu)
komentarz 19 maja 2015 przez MrWeb Stary wyjadacz (10,200 p.)
Dzięki, poczytam sobie jutro te artykuły z podanych linków.

Podobne pytania

0 głosów
1 odpowiedź 711 wizyt
pytanie zadane 13 maja 2019 w Inne języki przez Slegnawierzchowcu Użytkownik (860 p.)
0 głosów
0 odpowiedzi 174 wizyt
pytanie zadane 23 grudnia 2018 w Java przez Potopiec Obywatel (1,550 p.)
0 głosów
1 odpowiedź 187 wizyt
pytanie zadane 5 listopada 2018 w JavaScript przez molik Użytkownik (950 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...