Testy jednostkowe w bazach danych — jak to robimy w Sportmasterze, część druga

Pierwsza część — tutaj.

Testy jednostkowe w bazach danych — jak to robimy w Sportmasterze, część druga

Wyobraźcie sobie sytuację. Waszym zadaniem jest opracowanie nowej funkcjonalności. Macie materiały od swoich poprzedników. Jeśli założymy, że nie macie żadnych moralnych zobowiązań, co byście zrobili?

Najczęściej wszystkie stare materiały popadają w zapomnienie i wszystko zaczyna się od nowa. Nikt nie lubi grzebać w czyimś kodzie, a przy braku czasu, czemu nie stworzyć własnego systemu? To typowe podejście i w wielu przypadkach słuszne. Jednak w naszym projekcie postąpiliśmy inaczej. Podstawą przyszłego systemu automatycznego testowania były materiały z unit-testów na utPLSQL od naszych poprzedników, a następnie zaczęliśmy pracować w kilku równoległych kierunkach.

  1. Przywrócenie starych unit-testów. Przez przywrócenie rozumiemy dostosowanie testów do obecnego stanu systemu lojalnościowego oraz dostosowanie testów do standardów utPLSQL.
  2. Rozwiązanie problemu z zrozumieniem, co dokładnie, jakie metody i procesy mamy pokryte automatycznymi testami. Trzeba trzymać tę informację w głowie lub wyciągać wnioski na podstawie samego kodu automatycznych testów. Dlatego postanowiliśmy stworzyć katalog. Każdemu automatycznemu testowi przypisaliśmy unikalny mnemonik, stworzyliśmy opis i zapisaliśmy ustawienia (na przykład, w jakich warunkach powinien być uruchamiany, lub co powinno się zdarzyć, jeśli uruchomienie testu zakończy się niepowodzeniem). W istocie wypełniliśmy metadane dotyczące automatycznych testów i umieściliśmy te metadane w standardowych tabelach schemy utPLSQL.
  3. Określenie strategii rozszerzenia, tzn. wybór funkcjonalności, która ma być sprawdzana przez automatyczne testy. Postanowiliśmy zwrócić uwagę na trzy rzeczy: nowe usprawnienia systemu, incydenty z produkcji oraz kluczowe procesy systemu. W ten sposób rozwijamy się równolegle z wydaniem, zapewniając wyższą jakość, jednocześnie rozszerzając zakres regresji i zapewniając niezawodność systemu w krytycznych punktach. Pierwszym takim wąskim gardłem był proces przyznawania zniżek i bonusów na paragonie.
  4. Naturalnie, zaczęliśmy pracować nad nowymi automatycznymi testami. Jednym z pierwszych zadań po wydaniu było ocenienie wydajności zdefiniowanych zbiorów systemu lojalnościowego. W naszym projekcie znajdują się stałe bloki zapytań SQL, które wybierają klientów według określonych kryteriów. Na przykład, uzyskać listę wszystkich klientów, których ostatni zakup odbył się w konkretnym mieście, lub listę klientów, których średnia kwota zakupu jest wyższa od określonej wartości. Po napisaniu autotestów sprawdziliśmy zdefiniowane zbiory, ustaliliśmy wzorcowe parametry wydajności, a dodatkowo przeprowadziliśmy testy obciążeniowe.
  5. Praca z autotestami powinna być wygodna. Najczęściej wykonywane są dwa działania: uruchomienie autotestów i stworzenie danych testowych. W naszej systemie powstały dwa pomocnicze moduły: moduł uruchamiania i moduł generowania danych.

    Moduł uruchamiania jest przedstawiony w postaci jednej uniwersalnej procedury z jednym tekstowym parametrem wejściowym. Jako parametr można przekazać mnemonik autotestu, nazwę pakietu, nazwę testu, ustawienia autotestu lub zarezerwowane słowo kluczowe. Procedura wybiera i uruchamia wszystkie autotesty, które spełniają warunki.

    Moduł generowania danych jest przedstawiony w postaci pakietu, w którym dla każdego obiektu testowanego systemu (tabela w bazie danych) tworzona jest specjalna procedura, która wstawia tam dane. W tej procedurze maksymalnie wypełnione są domyślne wartości, co umożliwia tworzenie obiektów w dosłownie kilka chwil. Dla wygody użytkowania stworzono także szablony tworzonej danych. Na przykład, stworzyć klienta określonego wieku z testowym numerem telefonu i dokonanym zakupem.

  6. Autotesty powinny być uruchamiane i działać w akceptowalnym czasie dla twojego systemu. W związku z tym zorganizowano codzienne nocne uruchamianie, po którym tworzony jest raport z wynikami i wysyłany do całego zespołu deweloperskiego na pocztę firmową. Po przywróceniu starych autotestów i stworzeniu nowych całkowity czas pracy wyniósł 30 minut. Tego rodzaju wydajność odpowiadała wszystkim, ponieważ uruchomienie odbywało się poza godzinami pracy.

    Ale nad optymalizacją prędkości działania trzeba było popracować. Aktualizacja systemu lojalnościowego na produkcji odbywa się w nocy. W ramach jednego z wydań w nocy trzeba było nagle wprowadzić zmiany. Półgodzinne czekanie na wyniki autotestów o trzeciej nad ranem nie uszczęśliwiło osoby odpowiedzialnej za wydanie (gorące pozdrowienia dla Alekseja Wasiukowa!), a następnego ranka w stronę naszego systemu padło wiele ciepłych słów. Ostatecznie ustalono 5-minutowy standard pracy.

    Aby przyspieszyć wydajność, skorzystaliśmy z dwóch metod: autotesty zaczęły działać w trzech równoległych wątkach, co było bardzo wygodne dzięki architekturze naszego systemu lojalnościowego. Zrezygnowaliśmy również z podejścia, w którym autotest nie tworzy danych testowych dla siebie, lecz próbuje znaleźć coś odpowiedniego w systemie. Po wprowadzeniu zmian całkowity czas pracy skrócił się do 3-4 minut.

  7. Projekt z autotestami powinien być możliwy do uruchomienia na różnych środowiskach. Na początku pojawiły się próby napisania własnych skryptów, ale szybko zrozumieliśmy, że samodzielnie zaprojektowana automatyczna instalacja to całkowity koszmar, więc zwróciliśmy się ku rozwiązaniom przemysłowym. Ponieważ w projekcie jest bardzo dużo kodu (przede wszystkim przechowujemy kod autotestów) i bardzo mało danych (główne dane to metadane o autotestach), wdrożenie Liquibase było bardzo proste.

    To niezależna od bazy danych biblioteka open source do śledzenia, zarządzania i stosowania zmian w schemacie bazy danych. Jest zarządzana za pomocą wiersza poleceń lub frameworków typu Apache Maven. Zasada działania Liquibase jest dość prosta. Mamy uporządkowany projekt składający się z zmian lub skryptów, które należy zastosować na docelowym serwerze, oraz plików konfiguracyjnych, które określają, w jakiej kolejności i z jakimi parametrami należy zastosować te zmiany.

    Na poziomie bazy danych tworzona jest specjalna tabela, w której Liquibase przechowuje logi migracji. Każda zmiana ma obliczony hash, który jest porównywany pomiędzy projektem a stanem w bazie. Dzięki Liquibase łatwo wprowadzamy zmiany w naszym systemie na dowolnym środowisku. Testy automatyczne są aktualnie uruchamiane na testowych i produkcyjnych środowiskach, a także na kontenerach (osobistych środowiskach programistów).

Testy jednostkowe w bazach danych — jak to robimy w Sportmasterze, część druga

Zatem porozmawiajmy o wynikach stosowania naszego systemu testów jednostkowych.

  1. Przede wszystkim jesteśmy przekonani, że zaczęliśmy rozwijać oprogramowanie o wyższej jakości. Testy automatyczne są uruchamiane codziennie i podczas wydań wykrywają dziesiątki błędów. Część z tych błędów jest jedynie pośrednio związana z funkcjonalnościami, które naprawdę chcieliśmy zmienić. Mamy poważne wątpliwości, że te błędy zostałyby wykryte podczas testów manualnych.
  2. Zespół zyskał pewność, że konkretna funkcjonalność działa poprawnie… Dotyczy to w pierwszej kolejności naszych kluczowych procesów. Na przykład, w ciągu ostatnich sześciu miesięcy nie mieliśmy problemów z przydzielaniem zniżek i bonusów do paragonów, pomimo comiesięcznych zmian, chociaż w poprzednich okresach błędy pojawiały się z pewną regularnością.
  3. Udało nam się skrócić liczbę iteracji testowania. Dzięki temu, że testy automatyczne są pisane dla nowej funkcjonalności, do analityków oraz jednocześnie testerów trafia kod o wyższej jakości, ponieważ był już sprawdzony.
  4. Część osiągnięć w automatyzacji testów jest wykorzystywana przez programistów. Na przykład dane testowe w kontenerach są generowane przy użyciu modułu generowania obiektów.
  5. Nie bez znaczenia jest także to, że wśród programistów uwidoczniło się "przyjęcie" systemu automatyzacji testów. Jest zrozumienie, że to ważne i przydatne. Z doświadczenia mogę powiedzieć, że to wcale nie jest takie proste. Testy automatyczne trzeba pisać, należy je utrzymywać i rozwijać, analizować wyniki, a często te czasochłonne zadania po prostu nie są tego warte. Dużo łatwiej jest iść na produkcję i tam rozwiązywać problemy. U nas programiści ustawiają się w kolejce i proszą o objęcie ich funkcjonalności testami automatycznymi.

Co dalej

Testy jednostkowe w bazach danych — jak to robimy w Sportmasterze, część druga

Porozmawiajmy o planach rozwoju projektu automatyzacji testowania.

Bez wątpienia, dopóki system lojalności Sportmastera jest żywy i rozwija się, można również praktycznie w nieskończoność rozwijać automatyczne testy. Dlatego głównym kierunkiem rozwoju jest poszerzenie strefy pokrycia.

W miarę jak liczba automatycznych testów będzie rosła, całkowity czas ich pracy będzie nieuchronnie wzrastał, i znów będziemy musieli wrócić do kwestii wydajności. Najprawdopodobniej rozwiązaniem będzie zwiększenie liczby równoległych wątków.

Jednak to są oczywiste ścieżki rozwoju. Jeśli chodzi o coś bardziej nietypowego, wyróżniamy następujące:

  1. Obecnie zarządzanie automatycznymi testami odbywa się na poziomie bazy danych, tzn. wymagana jest znajomość PL/SQL do skutecznej pracy. W razie potrzeby można wydzielić jakąś administrację, np. wykorzystując Jenkins lub coś podobnego.
  2. Wszyscy lubią ilościowe i jakościowe wskaźniki. Dla automatycznego testowania takim uniwersalnym wskaźnikiem jest Code Coverage, czyli metryka pokrycia kodu. Dzięki temu wskaźnikowi możemy określić, jaki procent kodu naszego testowanego systemu jest pokrywany przez automatyczne testy. Od wersji 12.2 Oracle udostępnia możliwości obliczania tej metryki i proponuje używać standardowego pakietu DBMS_PLSQL_CODE_COVERAGE.

    Nasz system automatycznego testowania ma nieco ponad rok i być może teraz jest najlepszy czas na ocenę pokrycia. W moim poprzednim projekcie (projekt nie był związany ze Sportmasterem) tak właśnie się stało. Po roku pracy nad automatycznymi testami kierownictwo postawiło zadanie ocenić, jaki procent kodu pokrywamy. Przy pokryciu powyżej 1% kierownictwo byłoby szczęśliwe. My, programiści, oczekiwaliśmy wyniku w okolicach 10%. Przykręciliśmy pokrycie kodu, zmierzyliśmy i uzyskaliśmy 20%. Z radości poszliśmy po premię, ale jak ją zdobyliśmy i dokąd później poszliśmy, to już zupełnie inna historia.

  3. Automatyczne testy mogą sprawdzać wystawione usługi internetowe. Oracle spokojnie na to pozwala, a my już nie napotkamy szeregu problemów.
  4. Oczywiście, nasz system automatyzacji testów może być zastosowany w innym projekcie. Uzyskane przez nas rozwiązanie jest uniwersalne i wymaga jedynie użycia Oracle. Słyszałem, że w innych projektach Sportmaster jest zainteresowanie automatycznym testowaniem i być może się do nich wybierzemy.

Wnioski

Podsumujmy. W projekcie systemu lojalności w Sportmasterze udało nam się wprowadzić system automatyzacji testów. Jego podstawą jest rozwiązanie utPLSQL od Stevena Feuersteina. Wokół utPLSQL umieszczony jest kod testów automatycznych i pomocnicze samodzielne moduły: moduł uruchamiania, moduł generacji danych i inne. Testy automatyczne są uruchamiane codziennie i, co najważniejsze, działają i przynoszą korzyści. Wierzymy, że zaczęliśmy wydawać oprogramowanie o wyższej jakości. Przy tym uzyskane rozwiązanie jest uniwersalne i może być swobodnie stosowane w każdym projekcie, gdzie konieczna jest automatyzacja testów na systemie baz danych Oracle.

P.S. Artykuł ten jest dość mało konkretny: jest tu dużo tekstu i prawie brak przykładów technicznych. Jeśli temat jest ogólnie interesujący, to jesteśmy gotowi go kontynuować i wrócić z kontynuacją, w której opowiemy, co się zmieniło w ciągu ostatnich sześciu miesięcy i przedstawimy przykłady kodu.

Piszczie komentarze, jeśli są kwestie, na które warto zwrócić uwagę w przyszłości, lub pytania, które wymagają rozwinięcia.

Tylko zarejestrowani użytkownicy mogą brać udział w ankiecie. Zaloguj się, proszę.

Piszą czy o tym?

  • Tak, oczywiście

  • Nie, dziękuję

12 użytkowników zagłosowało. 4 użytkowników wstrzymało się od głosu.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster