Jak rozwiązać problemy z testowaniem monolitycznych aplikacji

W tym artykule opowiem o problemach z testowaniem aplikacji i o sposobie rozwiązania za pomocą użycia mikroserwisów.

Problemy z testowaniem

Pracowałeś kiedyś z aplikacjami, które pisane były latami? Wyobraźmy sobie pojedyncze repozytorium na kod rozwijane przez 10 lat. Jedna baza danych, która rozwijana była również 10 lat. W tym czasie w bazie danych powstają tabele liczące 100 pól a czasami nawet więcej. Każda część systemu komunikuje się z pozostałymi za pomocą bazy danych. Ilość kolumn w tabelach wciąż rośnie i nie są wydzielane nowe tabele tam gdzie to ma sens. Ale nie dzieje się tak dlatego, że programistom brakuje umiejętności. Nic z tych rzeczy. Winna jest architektura monolityczna i coupling, czyli silne zależności między elementami systemu, które wprowadzane są przez współdzieloną bazę danych.

Poza tym w związku z tym, że cały projekt i zawarte w nim aplikacje internetowe, serwisy, aplikacje desktopowe itp znajdują się w jednym repozytorium, to jakakolwiek zmiana w kodzie wymaga wdrożenia wszystkich części systemu. Prowadzi to do wdrażania naraz wielkich ilości kodu, który trzeba przetestować za każdym razem gdy publikujemy nową wersję aplikacji. Zwykle dzieje się to raz na 2 tygodnie, a czasami raz na 4 tygodnie. W tym czasie trzeba wykonać pełne testy regresji co trwa czasami dłużej niż jeden sprint.

Aby usprawnić testowanie w firmie pojawiają się różne pomysły:

  1. Zatrudnijmy więcej testerów manualnych aby skrócić testy regresji
  2. Zautomatyzujmy testy za pomocą Selenium
  3. Zorganizujmy szkolenia dla testerów aby zaznajomić ich z technikami ISTQB
  4. Zrezygnujmy z testowania w ogóle

Wszystkie te pomysły na pierwszy rzut oka wydają się sensowne. Nic bardziej mylnego. Dlaczego? Bo problem wcale nie tkwi w sposobie testowania, brakach kadrowych czy braku kompetencji. Problem tkwi dużo głębiej – źle zaprojektowana architektura systemu, która nie pozwala na jego dalszy rozwój.

Rozwiązanie – mikroserwisy

Kiedy już wiemy, że przyczyną wyżej wymienionych problemów z testowaniem jest błędnie dobrana architektura systemu to zastanówmy się co zrobić aby system był łatwi w testowaniu?

Na początku tworzenia aplikacji należałoby przyjąć odpowiednie podejście. Przykładowo moglibyśmy zaproponować następujące rozwiązania:

  1. Części aplikacji są wydzielane do osobnych repozytoriów
  2. Elementy aplikacji nigdy nie komunikują się za pomocą bazy danych
  3. Komunikacja między systemami odbywa się w sposób asynchroniczny za pomocą kolejek
  4. Nie stosujemy współdzielonych bibliotek, zamiast wspólnego kodu aplikacje współdzielą kontrakty, które definiują strukturę danych wymienianą między systemami
  5. Dzielimy monolityczną aplikację na mniejsze moduły, które można przepisać w ciągu 2 tygodni.

Jeśli jesteś na odpowiednio wczesnym etapie rozwoju Twojego systemu to zastanów się nad wdrożeniem w.w pomysłów aby mieć możliwość zbudowania systemu, który da się rozwijać i testować. Testowanie mniejszych modułów jest o wiele łatwiejsze i możliwe, że dzięki samemu dzieleniu aplikacji na mniejsze części nie będziesz miał żadnych problemów z testowaniem aplikacji i niekończącą się regresją. Oczywiście pojawi się konieczność testowania integracyjnego ale są do tego odpowiednie narzędzia.