Testy wydajnościowe – Jak przewidzieć zachowania systemu oraz skutecznie zapobiegać awariom?

Testy wydajnościowe – Jak przewidzieć zachowania systemu oraz skutecznie zapobiegać awariom?

W branży IT pojęcie testów i testowania pojawia się niezwykle często – szczególnie w pracy projektowej opartej o metodykę Agile zawsze znajdzie się miejsce dla testera. Jednym z często zaniedbywanych obszarów testowania jest ocena wydajności. Testowanie wydajności stanowi dobrą praktykę wytwarzania oprogramowania i pozwoli Ci zgromadzić istotne informacje na temat kondycji Twojej aplikacji.

Z tego artykułu dowiesz się, czym są testy wydajnościowe, dlaczego są potrzebne i jakie typy się wyróżnia. Do tego przedstawimy sytuacje, dzięki którym sam przekonasz się do testowania wydajnościowego.

Jakie są najczęściej spotykane testy?

W obiegu jest wiele typów i poziomów testów, które dodatkowo wchodzą w relację między sobą, co z początku może Cię przytłoczyć.

Testy można wykonać w sposób manualny (ręczny) lub zautomatyzowany. Podstawowy podział zakłada istnienie testów funkcjonalnych, testów niefunkcjonalnych, testów ​​strukturalnych oraz testów związanych ze zmianami (regresja). Z uwagi na poziom testowania wyróżniamy testy jednostkowe, testy integracyjne, testy systemowe i testy akceptacyjne. Niezależnie od tego, jaki typ testów wybierzemy, mają one wspólne cele – minimalizowanie ryzyka związanego z wdrożeniem produktu, zapewnianie jakości oraz spełnianie oczekiwań właścicieli i ich klientów.

Poznaj kilka faktów na temat testów wydajności

W większości projektów zachodzi potrzeba przeprowadzenia testów wydajnościowych, dlatego w poniższym rozdziale chcielibyśmy skupić się na najważniejszych cechach tego typu testowania.

Czym są testy wydajnościowe i w jakim celu się je wykonuje?

Testy wydajnościowe (ang. Performance Testing) należą do grupy testów niefunkcjonalnych, które – ogólnie rzecz biorąc – określają, JAK działa system. Polegają na symulacji ruchu w systemie na podstawie przygotowanych skryptów. 

Testowanie wydajnościowe pozwala odpowiedzieć na pytanie, jakie obciążenie system jest w stanie stabilnie obsłużyć (np. czas odpowiedzi w przypadku pracy z dużą liczbą zapytań, przyjęcia przez system dużej liczby danych) oraz czy w ramach zdefiniowanego obciążenia nadal będzie wykonywał działania jak w normalnych warunkach. Chodzi o to, by symulować zachowania użytkowników w kontrolowanym środowisku, zanim efekty wystąpią w środowisku produkcyjnym. Okazuje się to szczególnie przydatne dla systemów działających w dużej skali.

Rodzaje testów wydajnościowych

W zależności od aspektu działania aplikacji, który który chcemy poddać testom w warunkach wzmożonej aktywności, możemy wskazać kilka typów także w obrębie testów wydajnościowych.

Typy testów wydajnościowych
  • Load Testing – Jak system radzi sobie w warunkach spodziewanego obciążenia (tj. obciążenie nie przekracza punktu krytycznego)? Pomaga to w identyfikacji wąskich gardeł, które zakłócają pracę aplikacji.
  • Stress Testing – Czy system jest zdolny do działania przy ekstremalnym obciążeniu?
  • Spike Testing – Jak aplikacja reaguje na nagłe, duże skoki obciążenia?
  • Endurance Testing – Czy oprogramowanie jest w stanie wytrzymać wzmożony ruch przez długi okres czasu?
  • Volume Testing – Jak na symulowane obciążenie reaguje system, który przechowuje i przetwarza dużą liczbę danych?
  • Scalability Testing – W jakim stopniu aplikacja jest skalowalna w wyniku zwiększonego ruchu?

Testy wydajnościowe: Czy naprawdę ich potrzebujesz?

Testy pod kątem wydajności dają nam pełny obraz funkcjonowania systemu czy aplikacji. Dowiedz się, jak cenna dla biznesu jest każda sekunda w kontekście ładowania zasobów i na co się narażasz, pomijając etap testowania.

Co zyskujesz dzięki testowaniu wydajności?

Testy wydajnościowe pełnią ważną rolę na drodze do zapewnienia jakości i minimalizują ryzyko wystąpienia problemów, ponieważ dzięki nim można wcześniej odszukać i naprawić błędy, które zostały wygenerowane poprzez wzmożony ruch. Mając jasno określone granice możliwości technicznych aplikacji, jesteśmy w stanie oszacować zasoby niezbędne do poprawnego działania. W wyniku testów wydajności system uodporni się na przeciążenie, a Ty będziesz przygotowany na nagłe, niespodziewane wzrosty liczby użytkowników (bez obaw o stabilność i dostępność serwisu). W końcowym efekcie możesz liczyć na wzrost zadowolenia klienta.

Jakie są zagrożenia związane z brakiem testów wydajnościowych?

System potrafi obsłużyć skończoną liczbę zapytań i działa bardzo dobrze w ograniczonym środowisku, a jego słabości uwidaczniają się dopiero po zwiększeniu ruchu. Jeśli strona cieszy się nagle bardzo dużym zainteresowaniem, sytuacja wymyka się spod kontroli. Dochodzi do przeciążenia serwera i zawieszenia systemu – klient nie może się zalogować, sfinalizować zamówienia, czyli nie może liczyć na sprawną obsługę. Takie zaniedbania oznaczają, że nie uda się osiągnąć celów biznesowych i poniesiemy duże straty finansowe, a także spowodują zmiany wizerunkowe firmy. Oprócz tego brak optymalizacji pod względem wydajności i szybkości ładowania stron będzie się wiązać ze spadkiem naszej pozycji w wynikach wyszukiwania.

Przypadki testowe

Do omówienia przypadków wykorzystamy K6 – nowoczesny pakiet do przeprowadzania testów wydajnościowych, dzięki któremu można zweryfikować biznesowe i techniczne założenia projektu. K6 jest narzędziem opartym o open source, stworzonym z myślą o zespołach inżynierskich, m.in. testerach, QA, DevOps. Testy K6 mogą funkcjonować również jako usługa w chmurze.

Test cases
  • Scenariusz z życia produktu #1

Wykonujemy usprawnienia optymalizacyjne, które powinny polepszyć działanie produktu. Nie przewidujemy wpływu na zwiększenie liczby użytkowników, ale zmiany mogą oddziaływać na wewnętrzne procesy systemu.

Przykład: Aktualny ruch użytkowników generuje 80% obciążenia serwera – Czy po wdrożeniu zmian obciążenie serwera spadnie?

Prawdziwy przypadek

Usprawniono działanie jednej z funkcjonalności (szybsze generowanie obrazków na stronie), a do tego zaktualizowano kilka bibliotek, które były potrzebne do optymalizacji.

Po wdrożeniu efekt był odwrotny do oczekiwanego: system działał gorzej przy takim samym ruchu użytkowników. Strony ładowały się bardzo długo bądź nie ładowały się wcale. Błędne było założenie, że proces wyświetlania strony będzie działał poprawnie dla wszystkich użytkowników, gdy poprawią się wyniki dla pojedynczego użytkownika. Faktem było, że strona z obrazkiem miała lepszy czas ładowania, ale to nie sprawdziło się dla większej liczby użytkowników. Założenie uwzględniało ostateczny wynik, jednak pominięte zostały niektóre procesy systemu, które muszą zadziałać, aby ten efekt osiągnąć. Procesy nie były kontrolowane przy testach manualnych, ponieważ tego typu testy nie mogły wskazać niewielkiej różnicy w zapotrzebowaniu na zasoby systemu.

Rozwiązanie

Jako typ testu należy wybrać testowanie obciążenia (Load Testing), ponieważ zakładane zachowanie użytkowników nie ulega zmianie, a jedynie następuje weryfikacja systemu. W tym przypadku trzeba przyjąć, jaki ruch użytkowników jest stały i porównać wyniki przed oraz po zmianach.

Optimization attempt resulted in poor system performance with increased load. Load testing is recommended to assess changes' impact.

Źródło: https://k6.io/docs/test-types/load-testing/

  • Scenariusz z życia produktu #2

Wdrażamy nową funkcjonalność, a dział marketingu ją promuje i zachęca użytkowników do wypróbowania. Spodziewany jest ruch aktywnych użytkowników, ale oprócz tego mogą pojawić się użytkownicy, którzy przez długi czas nie byli aktywni. Dodatkowy ruch może być również generowany przez przypadkowych gości na stronie, którzy dopiero zainteresowali się funkcjonalnością.

Przykład: Obecny ruch użytkowników generuje 80% obciążenia serwera – Co się stanie, gdy osiągniemy 90%, 95%, 100% obciążenia? W jaki sposób architektura naszego produktu będzie próbować się bronić, aby działać stabilnie? Co się stanie, gdy liczba użytkowników wzrośnie do 120% lub nawet 150%?

Prawdziwy przypadek

W krótkim czasie (15 min po udostępnieniu wiadomości w social mediach) ogromne zainteresowanie użytkowników spowodowało niedostępność całego produktu. Serwery padły, ponieważ nie były w stanie poprawnie funkcjonować. Doprowadziły do tego błędy w konfiguracji środowiska oraz w zapytaniach do bazy danych, które wykorzystywały za dużo zasobów serwera i nie były zoptymalizowane.

W rezultacie tylko część użytkowników zdążyła poznać nową funkcjonalność. Pozostali mieli już negatywne opinie na temat działania produktu.

Rozwiązanie

Jako typ testu należy wybrać testowanie przeciążeniowe (Stress Testing), ponieważ zakładane zachowanie użytkowników może ulec zmianie w krótkim czasie. W tym przypadku trzeba znać typowy ruch użytkowników, ale również założyć znaczny ich wzrost do różnych wartości.

Massive user influx led to product unavailability due to configuration and database errors. Stress testing is advised to handle rapid traffic spikes.

Źródło: https://k6.io/docs/test-types/stress-testing/

W przedstawionych przypadkach nasuwa się pewna analogia. Zaniedbując testy wydajnościowe, oba produkty musiały stawić czoła poważnym problemom. 

Należy mieć na względzie, że tworzenie oprogramowania nie ogranicza się jedynie do pisania kodu zgodnie ze specyficznymi wymaganiami klienta, a później “jakoś to będzie”. Testowanie to ważny etap wytwarzania produktu, który z biznesowego punktu widzenia warto zaplanować wcześniej. Obecnie mamy do czynienia z coraz bardziej rozbudowanymi aplikacjami posiadającymi różnorodną architekturę oraz skomplikowaną logikę. Wykorzystywanie wielu technologii niesie ze sobą trudne do przewidzenia zależności między komponentami. Dobór narzędzi oraz możliwość weryfikacji poprawnego działania ma kluczowy wpływ na końcowy sukces produktu. Dzięki wykonanym testom mamy pewność, że aplikacja nie będzie stwarzać problemów, a stabilne i szybkie działanie zostanie docenione przez użytkowników.

Jak z biznesowego planu przejść do technicznego wykonania testu? Na to i inne pytania odpowiemy w kolejnym artykule.