Najlepsze praktyki dotyczące strategii testowania dla zespołu Scrumowego

Scrum minus plan testów to POC na sterydach.

W dzisiejszych czasach większość udanych projektów rozpoczyna się od weryfikacji koncepcji (POC), stosunkowo niewielkiej oceny pomysłu, w ramach której wybrana technologia i pakiet funkcji zostaną najpierw zweryfikowane, ocenione pod kątem potencjalnego wpływu na użytkowników biznesowych, a następnie, po sprawdzeniu warte inwestycji, pełnowymiarowy zespół projektowy zostaje przydzielony do zaprojektowania i dostarczenia w pełni funkcjonalnego produktu oraz wdrożenia go do produkcji.

To idealny przypadek dla zespołu Scrum. Zespół może szybko opracować prototyp, dodając istotne nowe funkcje w każdym sprincie, podczas gdy użytkownicy biznesowi mogą obserwować w czasie rzeczywistym szybkie postępy i sposób, w jaki pomysł jest budowany od podstaw w ciągu zaledwie około 10 sprintów. Pozostawia silne wrażenie (co i tak jest głównym celem POC), ale ma też jedną istotną właściwość – minimalną lub żadną aktywność testową, a samo myślenie o procesie testowania byłoby zwykłym żartem.

W zespole Scrumowym nie jest to zabawna czynność, a ludziom spodoba się głównie pomysł rozwijania bez procesów, które mogłyby ich spowalniać. To jest zasadniczo to, co każde działanie testowe zrobi niejawnie. A kto nie chce niepotrzebnego spowolnienia w czasie, którego potrzebujemy, aby zrobić największe wrażenie na użytkowniku końcowym?

Stan, który ma miejsce, gdy zespół projektowy kontynuuje w ten sam sposób po zakończeniu okresu POC, nazywam POC na sterydach – system produkcyjny powiększa się pod względem wielkości i funkcji, ale wciąż zachowuje się jak POC – niedoszły kompletny produkt z ukryte wady i niezbadane przypadki narożne, czekające tylko na poważną awarię.

Ale zanim się tam przekształci, zespołowi będzie trudniej ze sprintu na sprint nadążać za stabilnymi wydaniami, ponieważ naprawianie problemów z toczeniem się stanie się tylko bardziej złożone.

Oto kilka technik, które sprawdziły się, gdy miałem do czynienia z podobnymi problemami i które, jak sądzę, można nazwać najlepszymi praktykami wdrażania solidnych procesów testowania, wciąż bez nadmiernego zaśmiecania postępu programowania – ponieważ wszyscy chcemy być zespół Scrumowy.

Rozłóż ból

Od czego zacząć, gdy mamy do czynienia ze zbędnym zawracaniem sobie głowy, jak nie od dzielenia bólu :).

Rozumiem przez to stworzenie planu, który będzie wymagał niewielkiej dodatkowej aktywności ze strony programistów tu i tam, ale z biegiem czasu znacznie przyczyni się do osiągnięcia wspólnego celu, stopniowo, ale konsekwentnie.

# 1. Opracuj kod testu jednostkowego dla każdego utworzonego fragmentu nowego kodu

Jeśli uda Ci się przekonać swoje zespoły scrumowe, aby dodały do ​​swojej klauzuli Definition Of Done tworzenie testów jednostkowych dla każdego nowego kodu tworzonego w ramach sprintu, to z długoterminowej perspektywy będzie to wielkie osiągnięcie.

Powody są dość oczywiste:

Zmusi programistów do myślenia o różnych niestandardowych ścieżkach kodu. –

  • Takie testy jednostkowe można podłączyć do zautomatyzowanych potoków DevOps i wykonywać przy każdym wdrożeniu w środowisku deweloperskim lub testowym. Ponadto metryki z potoku można łatwo wyeksportować, a następnie wykorzystać do zademonstrowania użytkownikom biznesowym procentowego pokrycia przypadków testowych bezpośrednio powiązanych z kodem źródłowym.

Najważniejsze to zacząć bardzo szybko. Im później rozpoczną się prace nad testami jednostkowymi, tym bardziej rozpraszające będzie dla programistów dodawanie ich w ramach sprintu.

  • Opracowanie testów jednostkowych dla już istniejącego kodu będzie wymagało znacznego wysiłku. Niektóre części kodu mogą być tworzone przez innego programistę, a dokładna wiedza o tym, jak powinien działać w każdej pojedynczej części kodu, nie jest do końca jasna dla obecnego programisty. W niektórych przypadkach może dojść do tego, że dodanie testu jednostkowego do zmodyfikowanego kodu zajmie więcej czasu niż opracowanie zmiany funkcji dla sprintu (co jest stanem, którego na pewno nikt nie wyliczył podczas planowania sprintu).

#2. Zrób rutynę wykonywania wszystkich części testów jednostkowych w środowisku programistycznym

Nawet przed utworzeniem pull requesta w celu scalenia nowego kodu z gałęzią Master standardową czynnością powinno być przetestowanie zarówno kodu funkcji, jak i kodu testu jednostkowego w środowisku deweloperskim. W ten sposób zapewni się, że:

  • Kod testu jednostkowego faktycznie działa dla każdej części (w końcu jest to tylko kolejny kod, który należy zweryfikować). Ten krok jest bardzo często całkowicie pomijany. W jakiś sposób zakłada się, że jeśli test jednostkowy zostanie mimo to podłączony do potoku DevOps, ostatecznie zostanie gdzieś domyślnie wykonany i przetestowany. Jednak to nic innego jak zepchnięcie problemów na wyższe poziomy działań sprinterskich, gdzie zespół ma zwykle mniej czasu i więcej stresu na dokończenie każdej zaangażowanej historii.
  • Nowy kod funkcji jest testowany przez programistę pod kątem podstawowej funkcjonalności. Oczywiście po tym teście nie można oczekiwać, że funkcjonalność biznesowa zostanie w pełni zweryfikowana, ale przynajmniej ten test potwierdzi, że kod zachowuje się zgodnie z zamierzeniami programisty (pomijając na razie fakt, że logika biznesowa mogłaby zostać błędnie zrozumiane podczas opracowywania).

#3. Oczekuj wykonania testu jednostkowego po scaleniu kodu z gałęzią główną

Jedną rzeczą jest posiadanie funkcjonalnego kodu w lokalnym oddziale (gdzie nikt oprócz właściciela oddziału nie opracowuje nowej funkcji), ale zupełnie inną rzeczą jest mieć ten sam kod działający po żądaniu ściągnięcia i scalony z główną gałęzią.

Gałąź główna zawiera zmiany od innych członków zespołu Scrumowego i nawet jeśli konflikty zostaną rozwiązane i wszystko wygląda dobrze, kod po scaleniu i rozwiązaniu konfliktów jest w zasadzie wciąż nieprzetestowanym fragmentem kodu i ryzykowne jest wysyłanie go dalej bez uprzedniej weryfikacji nadal działa dobrze.

Więc to, co okazało się tutaj skuteczne, to po prostu poproszenie o wykonanie tych samych testów jednostkowych – już wykonanych wcześniej na środowisku dev – również na środowisku, które jest zbudowane z wersji kodu master branch.

Dla programistów może to być dodatkowy krok, który muszą wprowadzić do swojego życia, ale nie jest to duży wysiłek, ponieważ w tym przypadku nie trzeba wymyślać niczego nowego – wystarczy ponownie wykonać to, co już raz zostało zrobione.

Teraz ten krok można pominąć w jednym konkretnym przypadku:

  • Zautomatyzowane testy jednostkowe w potokach DevOps są tak wszechstronne, że obejmują już całe testy ręczne wykonywane na ich podstawie.

O ile osiągnięcie tego stanu jest jak najbardziej wykonalne, nigdy takiego stanu nie doświadczyłem w prawdziwym życiu. Tworzenie tak szczegółowych automatycznych testów jednostkowych byłoby prawdopodobnie zbyt czasochłonne dla programistów. Mogłoby być łatwo nie do zaakceptowania, gdyby właściciel produktu pozwolił zespołowi poświęcić tyle czasu na tę czynność, ponieważ miałoby to wyraźny wpływ na liczbę dostarczonych historii w ramach sprintu.

Jednak preferowanie treści sprintu nigdy nie powinno być wymówką do niewykonywania testów jednostkowych, a nawet ich minimalizowania. W ten sposób zespół ponownie przekonwertuje się do takiego stanu, że w kodzie brakuje zbyt dużego pokrycia testów jednostkowych, a potem na nadrobienie zaległości może być już za późno (znowu większy nakład pracy na ukończenie testów jednostkowych niż rzeczywisty zmiana kodu dla sprintu).

Z tych wszystkich powodów bez wahania poleciłbym ponowne wykonanie testów jednostkowych na wersji kodu głównego. To tak niewielki wysiłek w porównaniu z tym, jaką wartość przyniesie.

Dokona ostatecznego sprawdzenia gotowości gałęzi głównej do fazy testowania wersji. Pomoże również znaleźć większość błędów technicznych (np. błędów, które uniemożliwiają pomyślne wykonanie kodu źródłowego do pomyślnego zakończenia), pozostawiając do następnej fazy skoncentrowanie się wyłącznie na weryfikacji funkcjonalności biznesowej.

Przygotuj się do testów funkcjonalnych

Wszystkie dotychczasowe czynności testowe prowadzą do jednego konkretnego wniosku – kod gałęzi głównej jest wolny od błędów technicznych i wykonywalny bez problemów dla przepływów funkcjonalnych end-to-end.

Jest to faza, którą z łatwością może przejść jedna osoba, a ta osoba nawet nie musi mieć technicznego zaplecza.

W rzeczywistości znacznie lepiej jest, jeśli wykonuje to ktoś odłączony od programistów, ale z funkcjonalną świadomością tego, jak użytkownicy biznesowi oczekują zachowania kodu. Do wykonania są dwie główne czynności:

# 1. Ukierunkowany test funkcjonalny nowych historii sprintu

Idealnie każdy sprint powinien przynosić jakąś nową funkcjonalność (przyrost celu sprintu), której wcześniej nie było, a co za tym idzie podlegać weryfikacji. Ważne jest, aby nowe oprogramowanie działało w takim stopniu, aby użytkownicy biznesowi byli zadowoleni z jego posiadania, bo oczywiście czekali na niego co najmniej przez cały ostatni sprint :).

To takie smutne doświadczenie, kiedy (od dawna) obiecana funkcjonalność zostaje wreszcie ogłoszona, aby zostać udostępniona, tylko po to, by dowiedzieć się pewnego dnia, że ​​tak naprawdę nie działa dobrze.

Dlatego kluczowe znaczenie ma odpowiednie przetestowanie nowej funkcjonalności sprintu. Aby to się powiodło, dobrą praktyką jest zebranie ważnych przypadków testowych z wyprzedzeniem i od odpowiednich interesariuszy (albo od właściciela produktu, albo nawet od użytkowników końcowych) i sporządzenie listy wszystkich takich przypadków testowych potrzebnych do zawartości wewnątrz sprint.

Na pierwszy rzut oka może to wyglądać przytłaczająco, ale z mojego doświadczenia wynika, że ​​jest to całkowicie wykonalne dla jednej osoby. Ponieważ sprinty są w większości dość krótkie (jak okres dwóch tygodni), i tak prawie nigdy nie jest za dużo nowej treści, ponieważ sprint zawiera również dodatkowe działania, takie jak techniczne historie długów, dokumentacja, historie projektowania / skoków itp.

Następnie wykonywane są przypadki testowe, których celem jest przede wszystkim zweryfikowanie pożądanej funkcjonalności. Jeśli wystąpi jakikolwiek problem z wynikami, zwraca się tylko do odpowiedniego programisty (tego, który jest właścicielem zmian związanych z tą konkretną usterką), aby rozwiązać problem, miejmy nadzieję, szybko.

W ten sposób programiści poświęcą minimum czasu związanego z testowaniem funkcjonalnym i nadal będą mogli skoncentrować się na czynnościach, które lubią najbardziej.

#2. Wykonywanie przypadków testowych regresji

Inną częścią testów funkcjonalnych jest upewnienie się, że wszystko, co działało do tej pory, będzie działać również w następnej wersji. Do tego służą testy regresji.

Przypadki testowe do testów regresji są najlepsze, jeśli są regularnie konserwowane i przeglądane przed każdym wydaniem. W oparciu o konkretną specyfikę projektu najlepiej jest, aby były one proste, ale obejmowały większość bardzo podstawowych funkcjonalności i ważnych przepływów typu end-to-end przebiegających przez cały system.

Zwykle każdy system ma takie procesy, które dotykają wielu różnych obszarów, są to najlepsi kandydaci do przypadków testowych regresji.

W niektórych przypadkach testy regresji nawet domyślnie obejmują również nowe funkcje w sprincie, na przykład, jeśli nowa historia w sprincie zmienia określoną część istniejącego przepływu.

Tak więc w większości przypadków nie jest wcale bardzo skomplikowane przeprowadzanie testów regresji wraz z testami funkcjonalności nowych historii sprintu, zwłaszcza jeśli odbywa się to regularnie przed każdą wersją produkcyjną, a cykliczność wydań produkcyjnych nie jest zbyt mała.

Nalegaj na przeprowadzanie testów kontroli jakości przed każdą wersją produkcyjną

Test zapewnienia jakości (QA) jest ostatnim krokiem przed wprowadzeniem do produkcji i często ten test jest pomijany jako nieważny. Zwłaszcza jeśli zespół scrumowy jest zarządzany agresywnie w przypadku nowych treści.

Nawet użytkownicy biznesowi powiedzą, że są zainteresowani nowymi funkcjami, a nie zachowaniem funkcjonalności lub utrzymaniem niskiej liczby defektów. Ale z drugiej strony – z biegiem czasu jest to główny powód, dla którego zespół programistów będzie musiał w końcu zwolnić, a wtedy użytkownicy biznesowi i tak nie dostaną tego, o co proszą.

Test QA powinien być wykonywany wyłącznie przez osoby spoza zespołu Scrumowego, najlepiej przez samych użytkowników biznesowych w dedykowanym środowisku, jak najbardziej zbliżonym do przyszłej produkcji. Alternatywnie właściciel produktu może zastąpić użytkowników końcowych.

W każdym razie powinien to być czysty, funkcjonalny test z perspektywy użytkownika końcowego, bez żadnego związku z zespołem dev Scrum. Przedstawi jeden końcowy widok produktu i zostanie wykorzystany w sposób, którego prawdopodobnie nikt z zespołu scrumowego się nie spodziewał (nie jest to wcale idealny przypadek, ale na pewno może się zdarzyć). Jest jeszcze czas na poprawki w ostatniej chwili.

Alternatywnie, może się okazać, że oczekiwania nie zostały dobrze zrozumiane przez zespół scrumowy iw takim przypadku przynajmniej możemy uzgodnić plan działań następczych, jeszcze na długo przed faktycznym uruchomieniem produkcji. To znowu nie jest idealny przypadek, ale wciąż o wiele lepszy niż przyznanie się do porażki zaraz po zgłoszeniu udanej wersji produkcyjnej.

Gdzie dalej stąd?

Stosowanie tych praktyk w codziennej pracy ze scrumem może poważnie doprowadzić do bardziej ustabilizowanych i przewidywalnych nawyków dotyczących wydawania sprintów, bez opóźniania wydań produkcyjnych lub spędzania całego sprintu na przygotowaniach do następnego wydania, a nawet bez zmuszania wszystkich członków zespołu scrumowego do zrobienia czegoś, czego nie robią To znaczy tak naprawdę nie lubię lub nie wiem, jak to zrobić skutecznie przez większość sprintu.

Ale na pewno nie musisz się tutaj zatrzymywać.

Jednym z tematów do wymienienia jest włączenie testu wydajności. Są one często ignorowane lub uważane za niepotrzebne, usuwane w pierwszej rundzie „optymalizacji działań scrumowych”. Zawsze jednak miałem wątpliwości, jak można oczekiwać, że system produkcyjny będzie ewoluował w czasie, jeśli nie będzie regularnie sprawdzany pod kątem wydajności.

Przejście o jeden poziom wyżej oznacza również wprowadzenie testów automatycznych.

Omówiłem już jedną grupę testów automatycznych (testy jednostkowe w potokach). Możesz jednak opracować pełne testy regresji typu end-to-end, całkowicie zautomatyzowane i wykonywane samodzielnie po każdym wdrożeniu w środowisku testowym. To jeszcze bardziej odciążyłoby zespół scrum programistów, ale wymaga dedykowanego zespołu do opracowywania i utrzymywania takich zautomatyzowanych testów. Stałoby się to ciągłą pracą, ponieważ za każdym razem, gdy zmienia się kod produkcyjny, niektóre istniejące testy automatyczne mogą stać się nieważne, dlatego muszą być aktualizowane, aby kontynuować pracę w potokach. Jest to wysiłek, za który tylko nieliczni są gotowi zapłacić, korzyści dla zespołu dev scrumowego byłyby jednak świetne.

Są to tematy wykraczające daleko poza zakres tego artykułu i ustalanie odpowiedniego harmonogramu i czasu dla każdego wymienionego tutaj typu testów – tak, abyś mógł zrobić to w oknie sprintu. Z przyjemnością zanurkuję następnym razem!