Performance tests i load tests: zachowanie pod ruchem
- data
- kategoria
- Testing
- także w
- Capacity & Performance · Observability
- czytanie
- 2 min / 397 słów
System może zwracać poprawną odpowiedź i nadal być zepsuty.
Jeżeli checkout działa przy jednym użytkowniku, ale przy normalnym ruchu odpowiada po pięciu sekundach, test poprawności niczego nie uratował.
To jest miejsce dla performance tests, load tests i stress tests.
Co to za rodzaj testu
Performance test mierzy zachowanie systemu w czasie.
Może sprawdzać:
latency
throughput
czas startu
zużycie CPU
zużycie pamięci
liczbę zapytań do bazy
czas renderowania
Load test sprawdza system pod spodziewanym obciążeniem.
Stress test celowo wychodzi poza spodziewane obciążenie, żeby znaleźć granicę.
Te nazwy są blisko siebie, ale nie znaczą tego samego.
Performance test
Performance test może być mały.
Nie musi zawsze oznaczać wielkiego testu ruchu.
Przykłady:
funkcja przetwarza 10 000 rekordów poniżej 200 ms
endpoint nie robi więcej niż 3 zapytania do bazy
render tabeli mieści się w budżecie czasu
worker przetwarza batch bez wzrostu pamięci
Taki test łapie regresję kosztu.
Kod nadal daje poprawny wynik, ale robi to wolniej albo drożej.
Load test
Load test pyta:
czy system wytrzymuje ruch, którego się spodziewamy?
To wymaga scenariusza.
Nie wystarczy liczba requestów na sekundę.
Trzeba wiedzieć:
jakie endpointy
jaki rozkład ruchu
ilu użytkowników
ile zapisów
ile odczytów
jakie dane
jaki czas trwania
Load test bez realistycznego profilu ruchu jest łatwy do uruchomienia i trudny do interpretacji.
Stress test
Stress test pyta:
gdzie system pęka?
To nie jest test do codziennej bramki przy każdym pull requeście.
To narzędzie do poznania granic.
Dobry stress test mówi nie tylko, przy jakim obciążeniu system przestaje spełniać wymagania.
Mówi też, jak przestaje działać.
czy rośnie latency
czy pojawiają się 500
czy baza dobija do CPU
czy kolejka narasta
czy autoscaling nadąża
czy system degraduje się łagodnie
Co się dzieje, kiedy ich nie ma
Bez testów wydajnościowych performance zostaje opinią.
Ktoś mówi "powinno wystarczyć".
Ktoś patrzy na średni czas odpowiedzi.
Ktoś inny sprawdza tylko lokalnie.
Problem wychodzi dopiero wtedy, kiedy ruch jest prawdziwy.
Wtedy testem staje się produkcja.
Jeżeli nie ma obserwowalności, nawet wynik tego testu jest nieczytelny.
Budżety zamiast ogólnych oczekiwań
Performance test powinien mieć budżet.
p95 poniżej 300 ms
mniej niż 5 zapytań SQL
start poniżej 2 s
batch poniżej 1 GB RAM
checkout obsługuje 200 RPS przez 15 minut
Bez budżetu test tylko mierzy.
Z budżetem może zatrzymać regresję.
Budżet nie musi być idealny od początku.
Lepiej mieć prostą granicę i ją korygować niż mieć same wykresy bez decyzji.
Narzędzie ze stacka
Do load tests wybrałbym k6.
Jest wystarczająco prosty, żeby opisać scenariusz w kodzie, i wystarczająco blisko DevOps, żeby uruchamiać go z pipeline albo ręcznie przed większą zmianą.
Dla backendu Node testowałbym nim publiczne endpointy i krytyczne przepływy API.
Dla frontu nie zastępuje to testów renderowania, ale może sprawdzić backendowy koszt ścieżek używanych przez React.
Przykładowy sensowny cel:
checkout API utrzymuje p95 poniżej 300 ms przy spodziewanym RPS
Bez budżetu k6 jest tylko generatorem ruchu.
Z budżetem staje się bramką jakości.
Kiedy test jest mylący
Test wydajnościowy jest mylący, kiedy środowisko nie przypomina problemu.
inna baza
inne indeksy
inne limity CPU
brak TLS
brak cache miss
za mały dataset
brak konkurencji zapisów
Nie każdy test musi być produkcją.
Ale trzeba wiedzieć, czego test nie symuluje.
W przeciwnym razie wynik wygląda naukowo, ale opisuje inny system.
Ostatnia część serii dotyczy warstwy, którą często nazywa się konfiguracją, chociaż potrafi zepsuć aplikację równie skutecznie jak kod.