Load Testing vs Stress Testing: Differences, Metrics and k6 Examples
One proves your system handles the traffic you expect. Drugi dowiaduje się, gdzie pęka i jak się regeneruje. Learn when to run each, which numbers to trust, and how to plan a test that gives real answers.
- Load testing checks that a system meets its targets under expected traffic.
- Stress testing pushes past capacity to find the breaking point and study recovery.
- Narzędzia są zwykle takie same. What differs is the goal and the traffic pattern.
- Judge results with percentiles such as p95 and p99, since averages can hide serious problems.
Twoja aplikacja działa doskonale z dziesięcioma użytkownikami. Co się stanie w dniu sprzedaży z dziesięcioma tysiącami? Testowanie obciążenia a testowanie warunków skrajnych opisuje dwa różne sposoby odpowiedzi na to pytanie, a pomieszanie ich prowadzi do testów, które nie dowodzą tego, co myślisz.
W tym przewodniku wyjaśniono, co pokazuje każdy z nich, powiązane typy testów i sposób odczytywania wyników. We ran the small percentile calculation below on Python 3.13, with simulated numbers. The k6 scripts are illustrative examples that we did not execute, and the user counts and targets are invented, so replace them with your own. Przeprowadzaj te testy tylko na systemach, które posiadasz lub masz pozwolenie na testowanie, ponieważ duży ruch może wyglądać jak atak i powodować rzeczywiste awarie.
Krótka odpowiedź
A load test asks: can we handle the traffic we expect, and meet our targets while doing it? A stress test asks: how much can we take before we fail, how do we fail, and how quickly do we recover?
Pomyśl o moście. A load test drives the expected number of trucks across and confirms that it is fine. A stress test keeps adding weight to learn its limit, and whether it gives warning first. Fortunately, software is cheaper to break than a bridge.
Testowanie obciążenia i testowanie warunków skrajnych obok siebie
| Aspekt | Testowanie obciążenia | Testy obciążeniowe |
|---|---|---|
| Główne pytanie | Czy osiągamy cele przy oczekiwanym obciążeniu? | Gdzie i jak się łamiemy? |
| Poziom ruchu | Normalny do oczekiwanego szczytu | Poza oczekiwanym szczytem |
| Wzór | Podnieś się, trzymaj się stabilnie | Zwiększaj aż do porażki |
| Niepowodzenie | Nieudany test | Oczekiwany wynik |
| Kluczowe wskaźniki | Czas reakcji, przepustowość, błędy | Punkt krytyczny, tryb awaryjny, czas regeneracji |
| Typowy czas | Przed każdym większym wydaniem lub wydarzeniem | Po ustabilizowaniu się systemu pod obciążeniem |
| Wynik | Pass lub fiasko w przypadku celów | Limit wydajności i lista słabych punktów |
Co to jest testowanie obciążenia?
Testowanie obciążenia symuluje realistyczny oczekiwany ruch i mierzy zachowanie systemu. Wymaga celu, z którym będzie można przeprowadzić testy, na przykład: „przy 500 jednoczesnych użytkownikach 95% żądań realizacji transakcji kończy się w ciągu 800 ms, a liczba błędów wynosi poniżej 1%.
Oto jak może to wyglądać jako skrypt K6. Testy k6 są napisane w JavaScript i thresholds zamieniają Twoje cele na wynik pozytywny lub negatywny:
import http from "k6/http";
import { sleep } from "k6";
export const options = {
stages: [
{ duration: "5m", target: 500 }, // ramp up
{ duration: "20m", target: 500 }, // hold at expected peak
{ duration: "2m", target: 0 }, // ramp down
],
thresholds: {
http_req_duration: ["p(95)<800"],
http_req_failed: ["rate<0.01"],
},
};
export default function () {
http.get("https://staging.example.com/products");
sleep(1); // think time, as real users pause
}
sleep ma znaczenie. Bez zastanowienia każdy wirtualny użytkownik w sposób ciągły obciąża serwer, generując znacznie większy ruch niż ta sama liczba prawdziwych osób.
Co to są testy warunków skrajnych?
Testy warunków skrajnych celowo wykraczają poza oczekiwane poziomy. Nie próbujesz przejść. Chcesz uzyskać odpowiedzi na pytania takie jak:
- Na jakim poziomie wydajność zaczyna się pogarszać?
- Który komponent zawiedzie pierwszy: baza danych, serwery aplikacji czy połączenie strony trzeciej?
- Czy kończy się niepowodzeniem z wyraźnymi błędami, czy też ulega awarii i utracie danych?
- Czy samoczynnie się regeneruje, gdy ruch spada?
export const options = {
stages: [
{ duration: "5m", target: 500 }, // expected peak
{ duration: "5m", target: 1000 }, // beyond it
{ duration: "5m", target: 2000 }, // further
{ duration: "5m", target: 4000 }, // likely to break
{ duration: "10m", target: 0 }, // recovery: does it come back?
],
};
Często zapomina się o tym ostatnim etapie zdrowienia, a może on być najcenniejszy. System, który dobrze radzi sobie z awariami, ale nigdy nie odzyskuje sprawności bez ręcznego ponownego uruchomienia, nadal oznacza awarię, którą ktoś może naprawić w środku nocy. W idealnym przypadku system pod ekstremalnym obciążeniem powinien przerywać pracę w kontrolowany sposób, zwracając wyraźne 503 odpowiedzi zamiast przekraczać limit czasu.
Spike, moczenie i inne typy
Testy obciążeniowe i obciążeniowe należą do szerszej rodziny testów wydajnościowych:
| Wpisz | Wzór | Co znajdzie |
|---|---|---|
| Dym (wydajność) | Kilku użytkowników w skrócie | Czy skrypt i system w ogóle działają |
| Załaduj | Oczekiwany szczyt, utrzymany | Czy cele zostały osiągnięte |
| Stres | Rosnąca wydajność w przeszłości | Ograniczenia i tryby awarii |
| Spike | Nagły skok, potem upadek | Autoskalowanie i zachowanie kolejki |
| Moczyć (wytrzymałość) | Normalne obciążenie przez wiele godzin | Wycieki pamięci, kończące się połączenia |
| Pojemność | Stopniowy wzrost | Maksymalne obciążenie w obrębie celów |
Testy namaczania wychwytują problemy, których krótkie testy nigdy nie zauważą. A small memory leak can look harmless for twenty minutes, and only bring the service down after two days. Testy szczytowe są dostosowane do wydarzeń takich jak wyprzedaże błyskawiczne, podczas których ruch nie rośnie stopniowo.
Metryki, które mają znaczenie
| Metryczne | Znaczenie | Uważaj na |
|---|---|---|
| Czas reakcji (percentyle) | Jak długo trwają żądania | wzrasta p95 i p99 |
| Przepustowość | Żądania obsługiwane na sekundę | Spłaszczenie w miarę wzrostu liczby użytkowników |
| Poziom błędów | Procent nieudanych żądań | Jakikolwiek nagły wzrost |
| Procesor i pamięć | Wykorzystanie zasobów serwera | Nasycenie, czyli stały wzrost |
| Baza danych | Powolne zapytania, użycie puli połączeń | Wyczerpanie basenu, zamek czeka |
| Głębokość kolejki | Praca oczekująca na obróbkę | Wzrost, który nigdy nie wyczerpuje się |
Dlaczego średnie wprowadzają w błąd
Averages hide the slow requests that real people complain about. Aby to pokazać, wygenerowaliśmy 100 symulowanych czasów reakcji, z czego 95 było szybkich (80 do 200 ms), a 5 bardzo wolnych (2,5 do 4 sekund), a następnie obliczyliśmy typowe statystyki:
import math, random, statistics
random.seed(3)
times = [random.randint(80, 200) for _ in range(95)] \
+ [random.randint(2500, 4000) for _ in range(5)]
def pct(values, p):
values = sorted(values)
return values[math.ceil(p / 100 * len(values)) - 1]
print("avg", round(statistics.mean(times)), "p50", pct(times, 50),
"p95", pct(times, 95), "p99", pct(times, 99), "max", max(times))
# avg 302 p50 150 p95 199 p99 3740 max 3896
Przyjrzyj się uważnie tym liczbom. Średnia 302 ms nie opisuje nikogo. Typical requests took about 150 ms, while the slow ones took over 3 seconds. Even p95 looks healthy at 199 ms, and only p99 reveals the problem. A figure like p95 means 95% of requests were this fast or faster.
A jeden procent żądań nie jest rzadkością. If a page makes 50 requests, a slow p99 affects a large share of page views. Set targets on the percentiles that matter to you, and look at several together.
Wskazówka: Poszukaj „kolana” na swoich wykresach. As load increases, response times stay flat for a while, then suddenly climb, while throughput stops growing. That point is your practical capacity, and it often comes well before anything actually crashes.
Narzędzia
| Narzędzie | Skrypty | Znany z |
|---|---|---|
| k6 | JavaScript | Przyjazne dla programistów, progi dostosowane do CI |
| JMeter | GUI i XML | Dojrzały, obsługuje wiele protokołów |
| Gatlinga | Scala, Java, Kotlin i inne | Oparta na kodzie, wydajna |
| Szarańcza | Pyton | Proste zachowanie użytkownika oparte na języku Python |
Każdy z nich może uruchamiać zarówno testy obciążeniowe, jak i obciążeniowe. Pick the one that fits your team’s skills, rather than chasing a feature list. To use one in your pipeline, see what is CI/CD.
Jak zaplanować badanie
- Set goals. Use real analytics to find your peak traffic, and define targets.
- Choose journeys. Model realistic user behaviour, such as browse, search and checkout, in realistic proportions. Naciśnięcie tylko strony głównej niewiele daje.
- Use a realistic environment. A tiny staging server cannot predict production. Zanotuj wszelkie różnice.
- Prepare data. Use realistic volumes, because a query that is fast on 100 rows may crawl on 10 million.
- Warn people. Tell your operations team and any third parties, and do not load test a payment provider by accident. W stosownych przypadkach próbuj usług zewnętrznych.
- Start small. Run a small smoke test first to confirm that your script works.
- Monitor everything. Without server metrics, you will see that it slowed down, but not why.
- Repeat. Run it again after each fix, and keep a baseline to compare against.
Odczytanie wyników
| Objaw | Możliwa przyczyna |
|---|---|
| Powolne reakcje, ale niski procesor | Oczekiwanie na bazę danych, blokadę lub usługę zewnętrzną |
| Procesor bazy danych jest wysoki | Brakujące indeksy lub nieefektywne zapytania |
| Nagłe błędy połączenia | Osiągnięto limit puli połączeń lub plików |
| Pamięć stale rośnie | Wyciek lub nieograniczona pamięć podręczna |
| Procesor generatora obciążenia jest wysoki | Narzędzie testowe jest wąskim gardłem, a nie Twój system |
Databases are a common bottleneck, so if queries are the issue, read our guide to SQL query optimization. That final row of the table is an important trap: always check the health of the machine generating the load as well.
Typowe błędy
- Confusing users with requests. Be clear whether a target means concurrent users or requests per second.
- Leaving out think time. This inflates traffic and gives misleading results.
- Testing too late. A week before launch leaves no time to fix architecture problems.
- Using a single endpoint. Real traffic mixes reads, writes and searches.
- Caching hides everything. Identical repeated requests may only test your cache, so vary the data.
- Testowanie jednokrotne. Wydajność zmienia się z każdą wersją, dlatego regularnie przeprowadzaj testy.
Podsumowanie
Przeprowadź testy obciążenia, aby potwierdzić, że możesz obsłużyć oczekiwany ruch, oraz testy warunków skrajnych, aby dowiedzieć się, co się dzieje, gdy nie jest to możliwe. Start small: choose your most important user journey, set one clear target, and run a short test against staging with monitoring on. That first run usually teaches you something, and you can build from there.
Najczęstsze pytania
What is the main difference between load and stress testing?
Load testing checks behaviour under expected traffic against set targets. Stress testing goes beyond capacity to find the breaking point and how the system recovers.
Czy powinienem najpierw przeprowadzić testy obciążenia czy testy warunków skrajnych?
Najpierw wykonaj test obciążenia. Gdy system osiągnie swoje cele w ramach oczekiwanego ruchu, przeprowadź testy warunków skrajnych, aby zbadać jego ograniczenia. Wyniki obciążenia niewiele znaczą w niestabilnym systemie.
Jaka jest różnica między testem warunków skrajnych a testem szczytowym?
A stress test typically raises load step by step until failure. Test szczytowy nagle przechodzi na wysoki poziom, aby zobaczyć, jak system radzi sobie z nagłą zmianą.
Jaki jest czas reakcji p95?
Oznacza to, że 95% żądań zostało zakończonych w tym czasie lub wcześniej. Opisuje doświadczenia większości użytkowników lepiej niż przeciętny użytkownik.
Czy mogę uruchomić testy obciążeniowe na produkcji?
Można, ale ostrożnie, za pozwoleniem, monitorowaniem i sposobem na szybkie zatrzymanie. Większość zespołów zaczyna od środowiska testowego przypominającego środowisko produkcyjne, aby zmniejszyć ryzyko dla prawdziwych użytkowników.
Ucz się dalej
Potrzebujesz pomocy przy testowaniu, WordPressie lub SEO?
Pomagamy zespołom dostarczać lepsze oprogramowanie i rozwijać ich witryny. Powiedz nam, nad czym pracujesz, a my zaproponujemy jasny następny krok.
Więcej poradników na testowanie, sztuczna inteligencja i nowoczesny rozwój
Podobał Ci się ten artykuł? Wybierz temat i przejdź bezpośrednio do naszych najnowszych tutoriali.
Wyjaśnienie halucynacji AI: dlaczego modele językowe tworzą rzeczy i jak je zmniejszyć
Wyjaśniono halucynacje AI: czym są, dlaczego powstają w modelach językowych, typowe typy, jak je zredukować za pomocą uziemień i podpowiedzi oraz pr…
Przeczytaj artykuł →DevOpsWyjaśnienie zmiennych środowiskowych: pliki .env, sekrety i konfiguracja wykonana prawidłowo
Zmienne środowiskowe wyjaśnione na przykładach Pythona, które przeprowadziliśmy: ich odczytywanie i ustawianie, dlaczego każda wartość jest ciągiem …
Przeczytaj artykuł →Tworzenie oprogramowaniaWyjaśnienie ograniczenia szybkości interfejsu API: algorytmy, nagłówki i obsługa błędów 429
Ograniczanie szybkości API wyjaśnione za pomocą przeprowadzonej przez nas symulacji: zasobnik tokenów, stałe okno, przesuwane okno, 429 odpowiedzi, …
Przeczytaj artykuł →Automatyzacja testówWyśmiewanie w Pythonie: unittest.mock, patch i błędy, które sprawiają, że testy kłamią
Wyśmiewanie w Pythonie za pomocą unittest.mock, przetestowane: Mock i zwracana wartość, efekt uboczny, łatanie tam, gdzie używana jest nazwa, specyf…
Przeczytaj artykuł →Testowanie oprogramowaniaWyjaśnienie zasięgu kodu: pokrycie linii i oddziału oraz co naprawdę oznacza 100%
Wyjaśnienie pokrycia kodu za pomocą prawdziwego pliku cover.py: pokrycie linii, gałęzi i warunków, przeczytanie raportu, dlaczego 100% pokrycia może…
Przeczytaj artykuł →Bazy danych i SQLDELETE vs TRUNCATE vs DROP w SQL: różnice, wycofywanie i kiedy używać każdego z nich
DELETE vs TRUNCATE vs DROP wyjaśnione za pomocą przetestowanego SQL: co każdy usuwa, wycofywanie, wyzwalacze, resetowanie tożsamości, prędkość i czy…
Przeczytaj artykuł →Bazy danych i SQLWyjaśnienie widoków SQL: tworzenie, używanie i unikanie pułapek wraz z przykładami
Widoki SQL wyjaśnione za pomocą zapytań, które uruchomiliśmy: tworzenie widoku, wyniki na żywo, ukrywanie kolumn, wydajność, widoki z możliwością ak…
Przeczytaj artykuł →Tworzenie oprogramowaniaInterfejs TypeScript a typ: rzeczywiste różnice, testowane za pomocą kompilatora
Interfejs TypeScript a typ, sprawdzony z prawdziwym kompilatorem: co oba mogą zrobić, co tylko jeden, łączenie deklaracji, rozszerzenia a przecięcia…
Przeczytaj artykuł →Tworzenie oprogramowaniaPython *args i **kwargs wyjaśnione: elastyczne funkcje z przejrzystymi przykładami
Python *args i **kwargs wyjaśnione za pomocą uruchomionego przez nas kodu: pakowanie i rozpakowywanie, kolejność parametrów, argumenty zawierające t…
Przeczytaj artykuł →Tworzenie oprogramowaniaFunkcje Lambda w Pythonie: składnia, rzeczywiste zastosowania i kiedy ich nie używać
Funkcje lambda w Pythonie wyjaśnione za pomocą uruchomionego przez nas kodu: składnia, sortowanie za pomocą klucza, mapa i filtr, domknięcia, pułapk…
Przeczytaj artykuł →Sztuczna inteligencjaKim są agenci AI? Jak one działają, dzięki prostej pętli agenta, którą możesz uruchomić
Kim są agenci AI? Prosty przewodnik po pętli agenta, narzędziach, pamięci i poręczach, z małą pętlą w Pythonie, którą uruchomiliśmy, prawdziwymi zag…
Przeczytaj artykuł →DevOpsMonitorowanie a obserwowalność: prawdziwa różnica z logami, wskaźnikami i śladami
Wyjaśnienie monitorowania a obserwowalności: znane i nieznane awarie, dzienniki, metryki i ślady, opis incydentu przy kasie, złote sygnały, OpenTele…
Przeczytaj artykuł →DevOpsWoluminy platformy Docker a mocowania powiązań: utrwalanie danych kontenera we właściwy sposób
Wyjaśniono woluminy Dockera a montowanie powiązań: dlaczego dane kontenera znikają, nazwane woluminy, montowanie powiązań, tmpfs, przykłady tworzeni…
Przeczytaj artykuł →Automatyzacja testówTDD vs BDD: kluczowe różnice, jedna funkcja zbudowana w obie strony i kiedy używać każdej z nich
TDD vs BDD wyjaśnione za pomocą jednej funkcji rabatowej zbudowanej w obie strony: refaktoryzacja czerwono-zielona z uruchomionym przez nas kodem, s…
Przeczytaj artykuł →Testowanie oprogramowaniaTestowanie akceptacyjne użytkownika (UAT): proces, lista kontrolna i rzeczywiste przykłady
Wyjaśniono testy akceptacyjne użytkownika: kto je przeprowadza, czym różni się od kontroli jakości, siedmioetapowy proces, szablon przypadku testowe…
Przeczytaj artykuł →Bazy danych i SQLWyjaśnienie wartości SQL NULL: IS NULL, COALESCE, NULLIF i pułapki, których należy unikać
Wartości SQL NULL wyjaśnione za pomocą zapytań, które wykonaliśmy: logika trójwartościowa, IS NULL, COALESCE, NULLIF, w jaki sposób agregacje, łącze…
Przeczytaj artykuł →Bazy danych i SQLInstrukcja SQL CASE WHEN: składnia, rzeczywiste przykłady i typowe błędy
SQL CASE WHEN wyjaśnione za pomocą zapytań, które uruchomiliśmy: proste i przeszukiwane formularze, kolejność warunków, elementy przestawne z SUM, s…
Przeczytaj artykuł →Tworzenie oprogramowaniaCo to jest JWT? Tokeny internetowe JSON wyjaśnione na przykładzie działania
Co to jest JWT? Wyjaśniono tokeny sieciowe JSON: trzy części, token zbudowany i zmodyfikowany w uruchomionym przez nas kodzie, JWT a sesje, pamięć m…
Przeczytaj artykuł →Tworzenie oprogramowaniaWyjaśnienie pętli zdarzeń JavaScript: stos wywołań, mikrozadania i liczniki czasu z przykładami
Pętla zdarzeń JavaScript wyjaśniona za pomocą uruchomionego przez nas kodu: stos wywołań, kolejki zadań i mikrozadań, dlaczego setTimeout 0 nie jest…
Przeczytaj artykuł →Tworzenie oprogramowaniaWyjaśnienie generatorów Pythona i wydajności: oszczędzaj pamięć dzięki prawdziwym przykładom
Generatory Pythona i wydajność wyjaśnione za pomocą uruchomionego przez nas kodu: sposób wstrzymywania i wznawiania, mierzone oszczędności pamięci, …
Przeczytaj artykuł →Sztuczna inteligencjaCzym są osady? Wyjaśnienie wektorów i podobieństwa cosinusa
Czym są osadzania? Prosty przewodnik po wektorach, podobieństwie cosinusów i wyszukiwaniu semantycznym, z małym przykładem, który przeprowadziliśmy,…
Przeczytaj artykuł →DevOpsWdrożenie niebiesko-zielone a kanaryjskie: różnice, kompromisy i sposób wyboru
Wyjaśniono wdrożenie Blue-Green vs Canary: sposób działania każdego z nich, koszty, ryzyko i wycofywanie zmian, przetestowane przez nas stabilne łąc…
Przeczytaj artykuł →Automatyzacja testówNiestabilne testy: co je powoduje i jak je naprawić na dobre
Niestabilne testy wyjaśnione w przeprowadzonych przez nas demonstracjach: główne przyczyny, sposób potwierdzenia i zdiagnozowania jednej z nich, odp…
Przeczytaj artykuł →Testowanie oprogramowaniaLoad Testing vs Stress Testing: Differences, Metrics and k6 Examples
Wyjaśniono testy obciążenia i testy warunków skrajnych: co dowodzi każdy z nich, testy szczytowe i nasiąkania, istotne metryki, dlaczego średnie wpr…
Przeczytaj artykuł →Testowanie oprogramowaniaPrzypadek testowy a scenariusz testowy: kluczowe różnice, przykłady i kiedy stosować każdy z nich
Wyjaśnienie przypadków testowych i scenariuszy testowych: jasne definicje, tabela obok siebie, jedna funkcja resetowania hasła zaczerpnięta ze scena…
Przeczytaj artykuł →Bazy danych i SQLOptymalizacja zapytań SQL: czytaj plany wykonania i napraw powolne zapytania z synchronizacją
Optymalizacja zapytań SQL przetestowana na milionie wierszy: przeczytaj plany wykonania, dodaj odpowiednie indeksy, napraw filtry niesargowalne, uży…
Przeczytaj artykuł →Bazy danych i SQLSQL UNION vs UNION ALL: różnice, przykłady i testowana wydajność
SQL UNION vs UNION ALL wyjaśnione na podstawie zapytań, które uruchomiliśmy: duplikaty, obie reguły są zgodne, prawdziwy błąd danych, zmierzona wyda…
Przeczytaj artykuł →Tworzenie oprogramowaniaSamouczek API pobierania JavaScript: GET, POST, obsługa błędów i limity czasu
Samouczek JavaScript Fetch API testowany na serwerze lokalnym: GET i POST, dlaczego 404 nie rzuca, pomocnik wielokrotnego użytku, ciągi zapytań, prz…
Przeczytaj artykuł →Tworzenie oprogramowaniaObsługa plików w Pythonie: odczyt, zapis, CSV, JSON i pathlib z przykładami
Obsługa plików w Pythonie wyjaśniona za pomocą uruchomionego przez nas kodu: tryby otwarte, czytanie dużych plików, CSV, JSON, pathlib, pliki binarn…
Przeczytaj artykuł →Tworzenie oprogramowaniaGit merge vs rebase: różnice, przykłady i kiedy czego używać
Git merge vs rebase wyjaśnione na prawdziwym wyniku logu, z tabelą porównawczą, złotą zasadą rebase i bezpiecznym procesem pracy zespołu.
Przeczytaj artykuł →Tworzenie oprogramowaniaPython list comprehension: składnia, przykłady i kiedy jej unikać
Python list comprehension wyjaśnione: składnia, filtrowanie, if-else, zagnieżdżone pętle, zmierzone czasy i sytuacje, w których zwykła pętla for jes…
Przeczytaj artykuł →Bazy danych i SQLSQL JOIN – wyjaśnienie z przykładami (Inner, Left, Right, Full)
Zrozum złączenia SQL krok po kroku na przykładowych tabelach i zapytaniach: INNER, LEFT, RIGHT, FULL, CROSS i SELF, plus typowe błędy i wskazówki wy…
Przeczytaj artykuł →