1. Wprowadzenie do TDD
TDD zostaje osadzone w kontekście codziennej pracy programistycznej i porównane z tradycyjnym podejściem do tworzenia kodu. Uczestnicy poznają logikę cyklu Red-Green-Refactor, powody stosowania tej metody oraz najczęstsze błędne wyobrażenia związane z jej użyciem.
- Co to jest Test-Driven Development i dlaczego warto go stosować?
- Różnice między tradycyjnym podejściem a TDD,
- Cykl Red – Green – Refactor,
- Najczęstsze błędne wyobrażenia o TDD.
2. Podstawy testowania w Pythonie
unittest i pytest wyznaczają podstawowy warsztat pracy z testami automatycznymi w Pythonie. Sekcja pokazuje budowę prostego testu jednostkowego, różnice między tymi narzędziami oraz zastosowanie typowych asercji, takich jak assertEqual, assertTrue czy assertRaises.
- wprowadzenie do unittest – standardowego frameworka testowego w Pythonie,
- alternatywa: pytest – szybsze i prostsze testowanie,
- struktura prostego testu jednostkowego,
- przykładowe asercje (assertEqual, assertTrue, assertRaises, itp.).
3. Pierwsze kroki z TDD
Pisanie pierwszego testu przed kodem porządkuje sposób rozwijania funkcjonalności i wymusza precyzyjne określenie oczekiwanego efektu. Uczestnicy ćwiczą tworzenie minimalnej implementacji, refaktoryzację po uzyskaniu zielonego testu oraz powtarzanie tego cyklu dla kolejnych zmian.
- pisanie pierwszego testu przed napisaniem kodu,
- tworzenie minimalnego kodu spełniającego test,
- refaktoryzacja po przejściu testu,
- powtarzanie cyklu dla rozwoju większej funkcjonalności.
4. TDD na funkcjach i klasach
Testowanie funkcji i klas wymaga innego podejścia niż praca z pojedynczymi, prostymi przypadkami. Omawiane jest budowanie testów bottom-up dla funkcji, sprawdzanie zachowań obiektów w klasach i metodach oraz przygotowanie setupów i teardownów dla środowiska testowego.
- testowanie funkcji: podejście bottom-up,
- testowanie klas i metod – testowanie zachowań obiektów,
- tworzenie setupów (setUp) i teardownów (tearDown) w testach.
5. Zaawansowane techniki testowania
Gdy testowany kod zależy od API, bazy danych lub plików, potrzebne są techniki pozwalające kontrolować otoczenie testu. W tej części pojawiają się mocki i stuby z unittest.mock, parametryzacja w pytest oraz zasady organizacji większych zestawów testów.
- mockowanie i stubowanie w testach (unittest.mock),
- testowanie kodu zależnego od API, baz danych, plików,
- parametryzacja testów z użyciem pytest.mark.parametrize,
- organizacja większych zestawów testów w projekcie.
6. Best practices w TDD
Dobre praktyki w TDD wymagają nie tylko pisania testów wcześnie, ale też trafnego określania ich zakresu. Uczestnicy analizują, kiedy stosować testy jednostkowe, a kiedy integracyjne, jak traktować testy jako formę dokumentacji oraz jak unikać zbędnie rozbudowanych scenariuszy.
- kiedy pisać testy jednostkowe, a kiedy integracyjne?
- testy a dokumentacja kodu,
- jak unikać overengineeringu w testach?
- typowe pułapki w TDD i jak ich unikać.
6. Best practices w TDD
Dobór między testami jednostkowymi a integracyjnymi jest omawiany z perspektywy jakości kodu i kosztu utrzymania projektu. Sekcja porządkuje też rolę testów jako dokumentacji, wskazuje typowe pułapki TDD oraz sposoby ograniczania overengineeringu w warstwie testowej.
- kiedy pisać testy jednostkowe, a kiedy integracyjne?
- testy a dokumentacja kodu,
- jak unikać overengineeringu w testach?
- typowe pułapki w TDD i jak ich unikać.
7. Projekt praktyczny
Na przykładzie prostej aplikacji, takiej jak system zadań lub mini API, uczestnicy przechodzą przez pełny proces pracy w TDD. Każda zmiana zaczyna się od testu, a dalszy rozwój funkcji i refaktoryzacja są prowadzone z wykorzystaniem istniejącego zestawu testów.
- rozwój prostej aplikacji (np. system zarządzania zadaniami, mini API),
- stosowanie TDD na każdym etapie projektu,
- refaktoryzacja z wykorzystaniem testów.