Piramida testów
Piramida testów to fundamentalne pojęcie w świecie wytwarzania oprogramowania. Warto jednak pamiętać, że to jedynie uproszczony model — rzeczywistość bywa bardziej złożona.
Czym jest piramida testów?
Piramida testów to wizualna metafora opisująca optymalny rozkład różnych typów testów automatycznych w projekcie. Zaproponowana przez Mike'a Cohna, zakłada, że:
- dołem piramidy powinny być liczne, szybkie testy jednostkowe,
- w środku umiarkowana liczba testów integracyjnych,
- na szczycie nieliczne, ale kompleksowe testy E2E (end-to-end).
Kształt piramidy nieprzypadkowo jest trójkątem — im wyżej, tym mniej testów i tym droższe ich utrzymanie.
Testy jednostkowe (unit tests)
Testy jednostkowe to podstawa każdej strategii testowania. Testują pojedynczą jednostkę kodu — najczęściej metodę lub klasę — w izolacji od zewnętrznych zależności.
Cechy testów jednostkowych:
- Działają w milisekundach
- Nie wymagają bazy danych, sieci ani serwera
- Są łatwe do pisania i utrzymania
- Dają błyskawiczny feedback
W praktyce oznacza to mockowanie wszystkich zewnętrznych zależności i skupienie się wyłącznie na logice biznesowej. Przykład w Javie:
@Test
void shouldCalculateDiscountForPremiumCustomer() {
// given
Customer customer = new Customer(CustomerType.PREMIUM);
Order order = new Order(BigDecimal.valueOf(1000));
// when
BigDecimal discount = discountCalculator.calculate(customer, order);
// then
assertThat(discount).isEqualByComparingTo(BigDecimal.valueOf(100));
}
Testy jednostkowe powinny stanowić zdecydowaną większość wszystkich testów w projekcie — mówi się o proporcji 70–80%.
Testy integracyjne
Testy integracyjne weryfikują współpracę kilku komponentów systemu. W ekosystemie Spring Boot najczęściej obejmują:
- Spring Data — sprawdzają zapytania do bazy danych, mapowanie encji, repozytoria JPA
- Spring MVC / Spring WebFlux — testują kontrolery, serializację JSON, obsługę błędów HTTP
- Kontekst Spring — weryfikują konfigurację beanów i wstrzykiwanie zależności
@DataJpaTest
class OrderRepositoryTest {
@Autowired
private OrderRepository orderRepository;
@Test
void shouldFindOrdersByCustomerId() {
// given
Order order = new Order(42L, OrderStatus.NEW);
orderRepository.save(order);
// when
List<Order> found = orderRepository.findByCustomerId(42L);
// then
assertThat(found).hasSize(1);
}
}
Testy integracyjne są wolniejsze niż jednostkowe (często kilka sekund), ale dają pewność, że komponenty dobrze ze sobą współpracują. Powinny stanowić 15–20% wszystkich testów.
Testy E2E (end-to-end)
Testy E2E symulują rzeczywistego użytkownika korzystającego z aplikacji. Uruchamiają pełne środowisko — serwer, bazę danych, a często też przeglądarkę — i wykonują scenariusze jak prawdziwy użytkownik.
Zalety testów E2E:
- Weryfikują pełny przepływ biznesowy
- Wykrywają problemy integracji na styku systemów
- Testują UI i doświadczenie użytkownika
Wady:
- Są powolne (minuty, nie sekundy)
- Trudniejsze do debugowania przy awarii
- Bardziej podatne na niestabilność (tzw. flaky tests)
Ze względu na koszty, testów E2E powinno być relatywnie mało — skupionych na krytycznych ścieżkach biznesowych.
Strategia: jak ułożyć testy?
Przyjmując piramidę testów jako punkt wyjścia, rozsądna strategia wygląda następująco:
| Typ testu | Udział | Czas wykonania | |-----------|--------|----------------| | Jednostkowe | ~70% | milisekundy | | Integracyjne | ~20% | sekundy | | E2E | ~10% | minuty |
Kluczowe zasady:
- Testuj logikę biznesową jednostkowo — nie potrzebujesz Springa, żeby sprawdzić, czy rabat jest poprawnie naliczony.
- Testuj integrację z infrastrukturą — baza danych, zewnętrzne API, messaging — to najlepsze pole dla testów integracyjnych.
- Testuj E2E tylko krytyczne ścieżki — rejestracja, płatność, kluczowe przepływy biznesowe.
Podsumowanie
Piramida testów to nie dogmat, ale użyteczna heurystyka. Mówi nam: inwestuj w szybkie, tanie testy jednostkowe, bo dają największy zwrot z inwestycji. Uzupełniaj je testami integracyjnymi tam, gdzie testujesz granice systemu. Testy E2E traktuj jak ostatnią linię obrony dla najważniejszych scenariuszy.
W kolejnym wpisie zastanowię się, czy w dzisiejszych realiach — z Dockerem, TestContainers i nowoczesnymi frameworkami — piramida nadal ma sens.