Jak testować, by nie zwariować
W tym artykule chciałem rozwinąć temat jakości. Inspiracją jest komentarz znajomego – że testy się opóźniają i nigdy nic nie wychodzi na czas. To jak to zrobić, by testy nam przyśpieszały pracę. 🤔
Problemy dookoła testów
Często pomagam zespołom, którzy narzekają na testy w swojej codziennej pracy. Ale nie narzekają na testy pod względem technologicznym. Problemy jakie się pojawiają to:
Praca testerska pojawia się bardzo późno w procesie dostarczania.
Mamy wiele zwrotek z testów do wcześniejszych etapów. Dużo reworku.
Pozostali członkowie zespołu skupiają się na swoich zadaniach, nie pomagając testerom.
Praca testerska jest wąskim gardłem, tworzy się „górka testerska".
Testujemy po łebkach, byleby coś wypchać.
Testy automatyczne nie są pisane / są pisane po dostarczeniu.
Posiadamy testy w zespole, ale testy nam bardziej przeszkadzają niż pomagają. Stają się kotwicą, która nas ściąga na dno (efektywności).
Niedawno pisałem na LinkedIn:
Narzędzia nie działają. Praktyki działają.
Jak nie mamy odpowiednich procesów to samo testowanie nie działa. Mamy narzędzie jednej grupy. Trzeba je jeszcze odpowiednio wdrożyć do zespołu.
Procesy, które działają
A więc jakie procesy mieć?
Chcemy się skupić na tym by jakość było obywatelem pierwszej klasy. Proponuję tutaj 5 praktyk:
Jakość jako część definicji wykonania
Najważniejszym problemem jest brak priorytetu na zapewnianie jakości. Testy automatyczne są porzucane jako zbyt mało istotne w ramach pracy zespołowej. Developerzy skupiają się jedynie by wypchać jak najwięcej pracy.
Aby testy były dostarczane trzeba im nadać odpowiedni priorytet. Inaczej zawsze będą spadać w odchłań kolejki prac. Praca w zespole jest zakończona dopiero wtedy, kiedy całość jest przetestowana automatycznie i manualnie.
Można to przeprowadzić np. w ramach Definition of Done. Testy stają się elementem kontraktu w zespole. Częścią pracy nad nową funkcją jest odpowiednie zapewnienie jakości.
Tylko jak to zrobić by nie zabić prędkości dostarczania?
Przesunięcie jakości w lewo
Nie da się zapewniać jakości szybko, jeśli robimy to na samym końcu dostarczania. Pętla zwrotna jest zdecydowanie zbyt długa. Za duży rework.
Zagadnienia jakości (testy, wymagane atrybuty jakości) powinny być omawiane i przepracowywane możliwie najszybciej. Zamiast przeprowadzać tę pracę na końcu, trzeba to wykonywać na początku. Już w ramach analizy, designu, programowania warto angażować inżynierów jakości.
Jak to pisali w Implementing Lean Software Development Mary and Tom Poppendieck:
A quality assurance organization should champion processes that build quality into the code from the start rather than test quality in later.
To wymaga odpowiedniej współpracy w ramach zespołu.
Jakość jest własnością zespołu
W wielu zespołach testy są odpowiedzialnością 1-2 inżynierów jakości. O testach nawet się nie rozmawia po stronie innych członków zespołu. A przez to nie ma możliwości zastosowania praktyk shift-left jako całego zespołu.
Cały zespół powinien być odpowiedzialny za testy w projekcie. Nie chodzi o to, by każdy te testy pisał (chociaż może i warto do tego zachęcać). Ale powinniśmy wspólnie pracować nad tym aby:
Określać warunki brzegowe.
Wybierać, które przypadki użycia testować.
Definiować schematy API do testowania / tagi frontendu.
Przeprowadzać programowanie funkcji / testów w parach.
Jeśli zespół dba o testy, to testy automatyczne też muszą stać się produktem.
Testy automatyczne są kodem produktu
W wielu produktach testy są obywatelem drugiej kategorii. Kod testów jest chaotyczny, brakuje tam jakichkolwiek standardów. To sprawia, że ostatecznie nie da się tych testów utrzymywać.
Aby testy długofalowo dawały nam wartość musimy dla testów trzymać te same standardy co dla kodu funkcji. Dbać i wdrażać odpowiednie wzorce. Modernizować biblioteki. Refaktoryzować kod.
To się powiedzie, jeśli posiadamy odpowiednią współpracę Dev-QA. Developerzy uczą i rozwijają kompetencje inżynierów jakości w obszarze dbania o standardy. Dzięki temu każdy dba o testy.
Ale nawet wtedy można po prostu nie uruchamiać testów odpowiednio często…
Testy uruchamiane przy każdej zmianie
Testy, które nie są uruchamiane często dziczeją. Trwają bardzo długo. Są niedeterministyczne. Przez to nikt ich nie uruchamia.
Testy muszą być uruchamiane jak najczęściej. W zasadzie przy każdej integracji z główną gałęzią trzeba uruchamiać testy. Dzięki temu dostajemy feedback natychmiastowo. Czy to nie będzie bolesne, jeśli testy automatyczne słabo działają?
Takie podejście zadziała na nas jak Enabling Constraints – wymusi pisanie szybkich i stabilnych testów oraz podzielenie domeny tak, aby móc uruchomić tylko część testów. Jeśli nie narzucimy sobie takiego ograniczenia, to testy naturalnie nam się zdegenerują.
Martin Fowler pisał na blogu:
If it hurts, do it more often.
Podsumowanie
To jest 5 praktyk, które u mnie niesamowicie zadziałały. Spowodowały skrócenie czasu poświęcanego na testy, jednocześnie bardzo wysoko zwiększając ogólną jakość.
Co jeszcze polecisz?