<p>W dzisiejszym „odcinku”, chciałbym skupić się może nie tyle na samym TDD ale na testach jednostkowych. Co prawda ta seria wpisów, jak pisałem na początku, nie będzie się w jako takie testy się zbytnio zagłębiała, to jednak są pewne nierozłączne elementy o których należy powiedzieć w kontekście TDD. Te elementy to dobre praktyki pisania testów, o których należy pamiętać. Na samym początku zastanówmy się jednak, po co w ogóle przykładać uwagę do kodu testującego.</p>
<h2>Kod testujący a kod produkcyjny(testowany) </h2>
<p>Należy pamiętać, że kod testujący nie jest kodem drugiej kategorii. Co prawda nie wszystkie zasady dotyczące programowania się go tyczą, niemniej należy dbać o jego przejrzystość. Słyszałem opinie, że kod testujący nie podlega utrzymaniu. Jest to oczywiście brednia – nie zamierzam określać tutaj definicji utrzymania kodu, ale sam fakt, że do kodu testującego często się wraca – choćby po to, żeby czerpać korzyści z faktu, że dobrze napisany kod testujący może stanowić dobrą dokumentację projektu – wydaje mi się wystarczającym powodem, by był dobrej jakości. Do kodu testującego wraca się też by dokonać w nim zmian – nie jest to przecież pomnik w kamieniu i podlega zmianom wymagań.</p>
<h2>Zasady FIRST </h2>
<p>Dla testów jednostkowych został sformułowany zbiór 5 zasad, których akronim to FIRST. Są to:</p>
<p><b>Fast </b>– testy powinny być szybkie. W większości opracowań mówi się, że czas od uruchomienia testów do otrzymania rezultatu, powinien być krótszy niż sekunda.</p>
<p><b>Independent </b>– testy powinny być niezależne. Powinna istnieć możliwość wywoływania ich w dowolnej kolejności, i nie może mieć to wpływu na wynik.</p>
<p><b>Repeatable </b>– testy powinny być powtarzalne. Jeżeli uruchomimy testy 100 razy, to powinniśmy 100 razy otrzymać ten sam rezultat.</p>
<p><b>Self-checking</b> – rezultat testu ma powinien być określany automatycznie, bez udziału człowieka.</p>
<p><b>Timely </b>– testy powinny być pisane w tym samym czasie co kod produkcyjny.</p>
<p>Trzy z powyższych zasad, są stosunkowo łatwe do osiągnięcia. Są to literki I, R, i S. Ta łatwość wynika stąd, że są one w dużej mierze zależne od framework’ów wykorzystywanych do testowania. Większy problem stanowią zasady Fast i Timely. Pierwsza z nich, często jest niezależna od nas – np. wtedy gdy funkcjonalność dodajemy do zastanego kodu, który nie jest pokryty testami, i który w przypadku wielu zależności i dużej solucji, kompiluje się bardzo długo. Oczywiście w wypadku gdy piszemy nowy projekt, to już tylko od nas samych zależy jak szybko będą uruchamiały się testy. W przypadku timely, wszystko zależy od naszej dyscypliny – mam nadzieję, że jeżeli komuś chce się czytać ten artykuł, to również będzie mu się chciało pisać testy w odpowiednim czasie :).</p>
<h2>Dobre praktyki pisania testów jednostkowych</h2>
<p>Na koniec dzisiejszego posta, wspomnę o kilku kluczowych praktykach pisania testów jednostkowych.</p>
<ul>
<li>Jeden test testuje jedną rzecz.</li>
<li>Jeden test zawiera jedną logiczną asercję (to znaczy może zawierać kilka wywołań metod sprawdzających, ale muszą one być spójne – zwykle jest to po prostu kilka przypadków testowych)</li>
<li>Zawsze należy pamiętać o kroku Refactor, we wzorcu R-G-R.</li>
<li>Nie należy mylić testów jednostkowych z <a href="https://en.wikipedia.org/wiki/Integration_testing" target="_blank">testami integracyjnym</a>i.</li>
</ul>
<p>W kolejnej części postaram się przedstawić kolejny przykład, tym razem trochę bardziej złożony niż ostatnio (ale tylko trochę :)).</p>