PR Review - Usprawnienia - Zapewnianie jakości
Wspólnie z Krzysztofem Witczakiem stworzyliśmy serię artykułów, w których zastanawiamy się skąd tak duża popularność Pull Request Review, oraz jakie problemy Pull Request Review tworzy w naszych zespołach. Następnie podjęliśmy temat rozwiązywania kwestii PR Review i mierzenia, czy jest lepiej.
W serii PR Review:
Usprawnienia - Zapewnianie jakości [TEN ARTYKUŁ]
W poprzedniej części cyklu pisaliśmy o tym, w jaki sposób złagodzić ból związany z Code Review. Dziś przygotowaliśmy dla Was metody, które pomogą utrzymywać wysoką jakość bez potrzeby jego wykorzystania.
Rozwiązania na zachowanie jakości
Argumentem strony pro PR Review jest to, że taki model sprawdzania kodu zapewnia jakość.
Przygotowaliśmy więc praktyki, które pozwolą wam zachować jakość pomimo braku PR Review.
Continuous Integration
Możesz teraz powiedzieć: „Jak to, przecież narzędzie CI nie zapewni mi jakości”. I masz dużo racji. Ale jednocześnie się mylisz 😃
Nie chodzi nam tutaj o narzędzie (Jenkinsa, GitHub Actions, czy inne). Chodzi nam o praktykę Continuous Integration. Najlepiej wykorzystać tutaj fragmenty z ksiązki książki Continuous Delivery autorstwa Jez Humble i David Farley:
1. Szybkość integracji
The most important practice for continuous integration to work properly is frequent check-ins to trunk or mainline. You should be checking in your code at least a couple of times a day.
Integrujesz swój kod z głównym branchem przynajmniej raz dziennie. Wielkość twoich zmian jest na tyle mała, że kodu do sprawdzenia nie jest dużo. A to zmniejsza diametralnie liczbę potencjalnie wprowadzanych błędów.
2. Testy potwierdzające działanie
If you don’t have a comprehensive suite of automated tests, a passing build only means that the application could be compiled and assembled. It’s essential to have some level of automated testing to provide confidence that your application is actually working.
Uruchamiasz zbiór testów co integrację. Testy zapewniają, że twoja zmiana nic nie popsuła. Jeśli testy przechodzą, to wiesz, że jesteś gotowy by wrzucać na proda. A jeżeli nie ufasz swoim testom, bo są niedeterministyczne, musisz najpierw rozwiązać ten problem.
3. Build jest krótki i zawsze działający
Ideally, the compile and test process that you run prior to check-in and on your CI server should take no more than a few minutes, ten max. If the build breaks, the developers responsible are waiting to fix it. They identify the cause of the breakage as soon as possible and fix it.
Jeśli kod buduje się zbyt długo to naprawiacie build. Jeśli proces budowania się zepsuł to priorytetem zespołu jest naprawienie właśnie tego elementu. Aktywnie pracujesz, aby budowanie kodu dawało natychmiastowy feedback. Wg guide’ów XP szybki build to taki który trwa mniej niż 10 minut łącznie z testami.
4. Lokalne środowisko pracy
Developers should always work from a known good starting point when they begin a fresh piece of work. They should be able to run the build, execute the automated tests, and deploy the application in an environment under their control.
Środowisko pracy wspiera Cię, umożliwiając lokalne przeprowadzanie wszystkich testów. Posiadasz odpowiednią konfigurację i pliki startowe. Jesteś w stanie lokalnie odtwarzać błędy i testować zmiany.
Włączając w swoją pracę aspekty wymienione wyżej, zyskasz mechanizmy integracyjne, które umożliwią uniknięcie części problemów jakościowych dookoła PR Review.
Definiowanie i wdrażanie przypadków testowych
Sprawdzanie przypadków testowych już po napisaniu kodu sprawia, że przywiązujemy się do tego co napisaliśmy - skupiamy na rozwiązaniu, a nie na problemie. Co sprawia, że trudniej jest wyłapać, czy aby na pewno pokryliśmy wszystkie przypadki testowe.
Oto, co może tutaj pomóc:BDD – Behavior-Driven Development - projektowanie w oparciu o scenariusze użycia, jakie użytkownik oczekuje podczas interakcji z aplikacją.
TDD – Test-Driven Development – rozpoczynanie od napisania testów, a dopiero później przejście do napisania funkcji, która spełni testy.
Zastosowanie tych obu technik wymusza:
Myślenie przypadkami użycia i przypadkami brzegowymi (piszemy lepszy interfejs).
Wbudowywanie jakości w pisany kod od samego początku.
Zapewnienie, że nasz kod zawsze ma testy, przez co ufamy CI/CD.
Dzięki temu wcześnie wykrywamy problemy i redukujemy, lub nawet eliminujemy potrzebę ręcznych przeglądów kodu. Testy są uruchamiane automatycznie i natychmiastowo informują o problemach, co pozwala na szybką reakcję i korektę.
Ciekawie to podsumowuje Shormistha Chatterjee w swoim artykule o BDD vs TDD:
BDD – Build the right thing.
TDD – Build the thing right.
Both – Test first
Systematyczne i powtarzalne testy są bardziej efektywne i dokładne niż ręczna weryfikacja.
Z doświadczenia wiemy, że TDD jest trudne dla wielu developerów, ale jak wszystkie praktyki wymaga przećwiczenia. Często problemem są nasze luki w wiedzy dotyczącej właśnie pisania testów automatycznych i to, że zajmuje nam to więcej czasu niż powinno. Nie przejmuj się jednak – po paru tygodniach pracy w TDD ten problem znika.
Statyczna analiza kodu
Naszym celem jest, aby automatycznie potwierdzać wysoką jakość kodu i wymagane standardy zamiast wymuszać tą aktywność na kolegach z zespołu.
Co możemy wykorzystać?
Lintery kodu - sprawdzamy kod pod kątem zgodności ze zdefiniowanymi standardami stylu i składni. Unikamy więc nit-pickingu podczas review. Narzędzia to np. ESLint czy StyleCop.
Analiza jakościowa - zagłębiamy się w logikę i strukturę kodu, aby sprawdzić określone standardy jakości i bezpieczeństwa. Narzędzia to np. Sonarqube czy Coverity.
Testy zależności – potwierdzamy, że wszystkie zewnętrzne biblioteki i moduły, na których opiera się projekt, są aktualne i bezpieczne. Narzędzia to np. Dependabot, czy Renovate.
Standardy architektury - weryfikujemy zgodność ze standardami architektonicznymi, nazewnictwo klas, strukturę kodu.
Dzięki temu odpada nam duża część manualnej pracy podczas review. Spory kawałek zapewniania jakości przejmuje automat. Idealnie, jeżeli większość tej analizy możemy wykonać na lokalnej maszynie tak, aby nasz feedback loop był jak najkrótszy.
Monitoring i prewencja
Wraz ze zwiększeniem prędkości dostarczania i wzrostem złożoności systemu, część zapewniania jakości musimy przenieść na stronę post-wdrożeniową. A w tym pomaga nam obserwowalność.
Zamiast inwestować w kosztowne i czasochłonne testy E2E (które również zmagają się z problemami niedeterministyczności), skupiamy się na wdrażaniu mechanizmów obserwowalności. Wielkie firmy technologiczne, takie jak Netflix czy Amazon, już od dawna polegają na zaawansowanej obserwowalności zamiast na tradycyjnych metodach testowania. W środowiskach mikroserwisowych trudno o inną formę obrony.
Dziś skupiamy się na 2 aspektach obserwowalności – monitoringu i prewencji.
Monitoring, jak sama nazwa wskazuje, skupia naszą uwagę na monitorowaniu kluczowych scenariuszy naszego użytkownika. Dzięki niemu szybko wykrywamy problemy, zanim staną się krytyczne. Jesteśmy powiadamiani natychmiast o anomaliach i odchyleniach od normy.
Gdy już zaobserwujemy problemy mamy do dyspozycji szereg mechanizmów prewencji:
Wycofujemy zmian (manualnie lub automatycznie), gdy określone wskaźniki jakościowe się zmniejszą.
Wyłączamy scenariusz dla danego zbioru użytkowników bądź całkowicie (za pomocą feature flag).
Zmieniamy dynamicznie konfiguracje dotyczące bezpieczeństwa na bardziej restrykcyjne, gdy spodziewamy się ataku lub autoskalujemy w sytuacji, gdy wzmożony ruch jest uzasadniony.
W sytuacjach, gdy powyższe działanie nie jest możliwe, możemy automatycznie eskalować alert do zespołu na dev support duty.
Mechanizmy obserwowalności redukują potrzebę ręcznych przeglądów i testów, ponieważ system sam wykrywa i sygnalizuje potencjalne problemy. Automatyczne mechanizmy prewencyjne minimalizują ryzyko błędów, jednocześnie obniżając koszty związane z manualnymi procesami weryfikacji.
Nowoczesne firmy inwestują następnie w chaos engineering, aby zaobserwować czy infrastruktura, monitoring i automatyczna prewencja są w stanie poradzić sobie w stresujących sytuacjach. Takie “testy” dają nam znacznie większą pewność jakości i niezawodności niż testy e2e.
Więcej o tym opisał Radek w newsletterach:
Jak zwiększać zaufanie usprawniając PR Review?
Okazuje się, że jednym z głównych powodów przeprowadzania PR Review nie są problemy funkcjonalne, ale emocjonalne. Jak sobie z nimi poradzić i zbudować zaufanie kolegów i koleżanek z zespołu?
O tym piszemy w ostatniej, finalnej części cyklu:
PR Review - Usprawnienia - Zwiększenie zaufania