Automatyzacja testowania historycznie zaczęła się od pomysłu przyspieszenia i zmniejszenia czynnika ludzkiego w testach, jednak szybko okazało się, że testy automatyczne często zachowują się inaczej przy każdym uruchomieniu. Powtarzalność (repeatability) i deterministyczność to jedne z podstawowych wymagań jakościowych dla testów automatycznych, które powinny dawać ten sam wynik w tych samych warunkach.
Problemy zaczynają się z powodu niejawnych zależności: niestabilne dane testowe, niesynchronizowane środowiska, równoległe procesy lub zewnętrzne usługi. To prowadzi do flaky-testów — ich wyniki są nieprzewidywalne.
Rozwiązania koncentrują się wokół surowej kontroli środowiska wykonawczego, izolacji testów, obiektów mock/stub, danych statycznych i odtwarzalnych scenariuszy (na przykład czyszczenie i przygotowanie bazy danych przed każdym testem).
Kluczowe cechy:
Co zrobić, jeśli flaky-test występuje tylko w CI, a lokalnie wszystko jest stabilne?
To prawie zawsze związane jest z różnicami w środowiskach: wersje zależności, szybkość działania infrastruktury, równoległość, ustawienia systemu operacyjnego lub kolejność uruchamiania testów. Rozwiązaniem jest jak najbliższe dopasowanie środowiska CI do maszyny deweloperskiej (Docker, te same wartości seed, odpowiednie ustawienia setUp/tearDown w testach).
Czy można uznać testy parametryzowane za całkowicie deterministyczne, jeśli dane pochodzą z bazy?
Nie. Nawet jeśli dane bazowe się zgadzają, baza danych może się zmieniać między testami lub między wydaniami. Dla prawdziwej deterministyczności dane muszą być przygotowane i oczyszczane wyraźnie w każdym teście.
Czy użycie sleep w celu oczekiwania na załadowanie elementów rozwiąże problem niestabilności testów UI?
Nie. Sleep tylko maskuje problem i spowalnia wykonanie testów. Należy poprawnie używać oczekiwań jawnych (Explicit Waits), które czekają na konkretne warunki, a nie na określony czas.
W projekcie uruchamiano testy UI na środowisku, które nikt nie oczyszczał po testach ręcznych. Co kilka nocy testy nie przechodziły z „losowymi” błędami, których nie było lokalnie. Zespół dodał sleep w testach i zignorował problemy flaky.
Plusy:
Minusy:
Po pojawieniu się doświadczonego inżyniera DevOps zespół wdrożył skrypty do resetowania i inicjalizacji danych testowych, dodał usługi mock dla niestabilnych integracji i zaczął uruchamiać testy w kontenerach. Flaky-testy praktycznie zniknęły.
Plusy:
Minusy: