Przejdź do głównej zawartości

Testy obciążenia, stresu i benchmarków

Testowanie wydajności wspomagane AI polega na tym, że agent kodujący pisze skrypty k6 do testów obciążenia i stresu na podstawie progów opóźnień ustalonych przez człowieka, uruchamia je przez serwer MCP k6 i szereguje wąskie gardła według podsumowania k6 oraz danych z bazy. Werdykt wydają progi k6 i porównanie z linią bazową w CI, nigdy interpretacja agenta.

Ta strona jest dla programistów i liderów technicznych, którzy odpowiadają za budżet opóźnień usługi. Twoje API do składania zamówień wytrzymuje na stagingu 500 żądań na sekundę. W dniu premiery ruch rośnie trzykrotnie, pula połączeń z bazą się wyczerpuje, p95 skacze ze 120 ms do 4 s i nikt nie potrafi wskazać commita, który zjadł zapas. Poniższy przepływ pracy znajduje ten limit, zanim zrobią to użytkownicy.

  • Serwer MCP k6 podłączony do Claude Code, Codeksa i Cursora, dzięki czemu agent sam waliduje i uruchamia swoje skrypty
  • Pięć promptów do skopiowania: test obciążenia sterowany progami, test stresu szukający punktu załamania, ranking wąskich gardeł, pomiar front-endu pod obciążeniem i bramka porównania z linią bazową
  • Workflow CI z dwiema bramkami: bezwzględnymi progami przez kod wyjścia k6 run i bramką względną, która oblewa pull request, gdy p95 pogorszy się o ponad 20% względem zapisanej linii bazowej
  • Podział odpowiedzialności: ludzie ustalają progi i linię bazową, agent pisze skrypty i diagnozuje, k6 decyduje o wyniku
  • Sytuacje, w których liczby z testów obciążenia wprowadzają w błąd, i sposób wyjścia z każdej z nich

k6 to samodzielna binarka w Go, która uruchamia skrypty testowe w JavaScripcie. Zainstaluj ją według instrukcji instalacji k6 albo menedżerem pakietów (brew install k6). Nie uruchamiaj npm install k6: pakiet k6 w npm to niezwiązany placeholder w wersji 0.0.0.

Na k6 zainstaluj oficjalny serwer MCP od Grafany, grafana/mcp-k6. Daje agentowi cztery narzędzia: validate_script (jeden VU, jedna iteracja), run_script, list_sections i get_documentation. Serwer jest dystrybuowany jako binarka mcp-k6, obraz Dockera grafana/mcp-k6 albo podpolecenie k6 x mcp, które podłącza k6 x agent init, a nie jako pakiet npm, więc każdy „k6 MCP” uruchamiany przez npx traktuj jako nieoficjalny. Grafana oznacza mcp-k6 jako eksperymentalny (README, sprawdzone 2026-09-26; najnowsze wydanie v0.6.1), więc przypnij wersję, którą przetestowałeś.

Najszybciej skonfigurujesz wszystko podpoleceniem k6 x agent, które informacje o wydaniu k6 v2.1.0 opisują jako „Bootstrap an AI-assisted k6 testing workflow in any editor”. Wymaga k6 v2.1.0 lub nowszego (aktualnie: v2.3.0); starsze k6 zgłosi nieznane polecenie, a README mcp-k6 nadal opisuje k6 x mcp jako wymagające własnej kompilacji xk6. Uruchom k6 x, żeby wypisać wbudowane podpolecenia i potwierdzić, że są wśród nich agent i mcp, a potem uruchom je w katalogu głównym repozytorium:

Okno terminala
# Podgląd plików, które zostaną zapisane, a potem zapis
k6 x agent init claude-code --dry-run
k6 x agent init claude-code # inne cele: codex-cli, cursor, opencode, vscode-copilot, cline
k6 x agent status # co jest zainstalowane w tym projekcie
k6 x agent skills list # lista skilli wbudowanych w binarkę k6

Polecenie podłącza edytor do wbudowanego w k6 serwera k6 x mcp, więc osobna binarka mcp-k6 nie jest potrzebna, i instaluje skille k6 (k6-load-test, k6-smoke-test, k6-trend-analysis, k6-test-maintenance i inne). Dla Claude Code są to .mcp.json, .claude/settings.local.json i .claude/skills/, dla Codeksa .codex/mcp.json i .codex/skills/, dla Cursora .cursor/mcp.json i .cursor/rules/. Codex (sprawdzone w v0.157.1) czyta serwery MCP z config.toml, a nie z .codex/mcp.json: uruchom codex mcp list, a jeśli brakuje k6, zarejestruj go poleceniem codex mcp add k6 -- k6 x mcp (albo -- mcp-k6). Jeśli wolisz zarejestrować samodzielny serwer ręcznie, zainstaluj binarkę raz (brew tap grafana/grafana && brew install mcp-k6 albo docker pull grafana/mcp-k6:latest) i dodaj ją w każdym narzędziu:

Okno terminala
claude mcp add --scope user --transport stdio k6 -- mcp-k6
# Bez lokalnej binarki:
claude mcp add --scope user --transport stdio k6 -- docker run --rm -i grafana/mcp-k6

Do wydajności front-endu dodaj serwer MCP Chrome DevTools (chrome-devtools-mcp w npm). Nagrywa ślady wydajności (performance_start_trace) i rozkłada je na wnioski (insights), np. rozbicie LCP, więc do tego zadania pasuje lepiej niż Playwright MCP. Jego narzędzie lighthouse_audit obejmuje dostępność, SEO i dobre praktyki, ale pomija wydajność, dlatego mierz śladem. Domyślnie wysyła statystyki użycia do Google; wyłączysz to flagą --no-usage-statistics.

Okno terminala
claude mcp add chrome-devtools --scope user -- npx chrome-devtools-mcp@latest --no-usage-statistics

Pętla wygląda tak samo w każdym narzędziu. Liczy się to, kto odpowiada za który krok, bo agent, który pisze test, uruchamia go i ocenia wynik, sam sobie wystawia ocenę.

  1. Ty ustalasz cele. Opóźnienia p95 i p99, odsetek błędów i ruch, który usługa musi przetrwać, pochodzą z SLO albo od właściciela produktu, nie od agenta. Te liczby trafiają do thresholds w skrypcie.
  2. Agent pisze skrypt na podstawie tych celów, a potem wywołuje validate_script, żeby błąd składni lub importu wyszedł po jednej iteracji, a nie po ośmiu minutach przebiegu.
  3. Sprawdzasz kształt skryptu, nie każdą linię. Zweryfikuj cztery rzeczy: endpoint i metodę, czasy etapów, zgodność progów z tym, o co prosiłeś, oraz to, że host docelowy pochodzi ze zmiennej środowiskowej.
  4. Agent uruchamia test na stagingu przez run_script i raportuje, które progi nie przeszły.
  5. Agent szereguje wąskie gardła na podstawie podsumowania k6 oraz danych z bazy i APM z tego samego okna czasowego.
  6. Werdykt należy do CI. k6 kończy się niezerowym kodem, gdy próg nie przejdzie, a skrypt porównujący oblewa build, gdy p95 pogorszy się względem linii bazowej. Każdą zmianę progów lub linii bazowej zatwierdza lider techniczny.

Wygeneruj test obciążenia z twoich progów opóźnień

Dział zatytułowany „Wygeneruj test obciążenia z twoich progów opóźnień”

Zacznij od jednego endpointu i liczb, które podajesz sam. Skrypt z twoimi liczbami sprawdzisz w minutę; „napisz test obciążenia” daje wiarygodnie wyglądający skrypt z wymyślonymi wartościami.

Wynik powinien wyglądać mniej więcej tak: konkretne etapy, twoje progi i nic zaszytego na sztywno, co powinno pochodzić ze środowiska.

import http from 'k6/http';
import { check, sleep } from 'k6';
import { SharedArray } from 'k6/data';
const carts = new SharedArray('carts', () => JSON.parse(open('./data/carts.json')));
export const options = {
stages: [
{ duration: '2m', target: 200 },
{ duration: '5m', target: 200 },
{ duration: '1m', target: 0 },
],
thresholds: {
http_req_duration: ['p(95)<300', 'p(99)<800'],
http_req_failed: ['rate<0.01'],
},
};
export default function () {
const cart = carts[Math.floor(Math.random() * carts.length)];
const res = http.post(`${__ENV.BASE_URL}/api/checkout`, JSON.stringify(cart), {
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${__ENV.TOKEN}` },
});
check(res, { 'status is 200': (r) => r.status === 200 });
sleep(1);
}

Sposób wywołania różni się między narzędziami, prompt pozostaje ten sam.

Uruchom interaktywną sesję z zapisanym promptem jako pierwszą wiadomością:

Okno terminala
claude "$(cat prompts/perf-checkout.txt)"

Zanim agent pierwszy raz wywoła run_script, upewnij się, że BASE_URL wskazuje staging. Test obciążenia przez pomyłkę wycelowany w produkcję to awaria, którą sam wywołałeś.

Zapisz prompt w prompts/perf-checkout.txt, żeby następna osoba wygenerowała ten sam test. Realistyczne dane koszyków i użytkowników opisuje strona strategie danych testowych i fixtures.

Test obciążenia odpowiada na pytanie, czy usługa wytrzyma oczekiwany ruch. Test stresu odpowiada, przy jakim natężeniu przestaje wytrzymywać, i ta liczba trafia do planu pojemności. Zdefiniuj „awarię” przed przebiegiem, żeby test zwrócił liczbę, a nie wrażenie.

Użyj tu executora opartego na natężeniu napływu (arrival rate). Rampa VU pozwala przepustowości spadać, gdy rosną opóźnienia, więc test po cichu wysyła mniej ruchu dokładnie wtedy, gdy serwer ma problem.

Jeśli dropped_iterations rośnie wcześniej niż opóźnienia, generatorowi obciążenia zabrakło VU albo CPU, a „punkt załamania” należy do twojego laptopa. Zanim zaufasz tej liczbie, podnieś maxVUs albo przenieś przebieg na większą maszynę.

Czerwony próg mówi, że usługa jest wolna. Nie mówi, czy przyczyną jest zapytanie, pula połączeń, CPU aplikacji czy wywołanie zewnętrzne. Ta diagnoza to miejsce, w którym agent naprawdę pomaga, pod warunkiem że dostanie dowody z tego samego okna czasowego i będzie musiał je cytować.

Ostatnie zdanie promptu jest kluczowe: każda poprawka przychodzi z przebiegiem, który ją udowadnia. Wprowadź zmianę, uruchom ten sam skrypt i porównaj p95. Pętlę zamyka pomiar, a nie wyjaśnienie agenta.

Żeby powiązać nieudane progi z błędami i wolnymi transakcjami po stronie serwera, dodaj serwer MCP Sentry (zdalny, OAuth) i poproś agenta o zestawienie najwolniejszych transakcji z Sentry w oknie testu z porażkami k6:

Okno terminala
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp

Omijaj pakiet npm o nazwie sentry-mcp: to niezwiązany stub w wersji 0.0.1. Własny pakiet stdio Sentry to @sentry/mcp-server, przeznaczony dla Sentry hostowanego samodzielnie.

Większość nagłych skoków opóźnień w testach obciążenia prowadzi do zapytania, które było szybkie przy danych z seeda. Gdy ranking wskaże takie zapytanie, poproś agenta o benchmark z proponowanym indeksem i bez niego przy produkcyjnej liczbie wierszy (na przykład 1 mln i 10 mln), z wynikiem EXPLAIN (ANALYZE, BUFFERS) jako dowodem. Strojenie po stronie produkcji po wdrożeniu opisuje strona optymalizacja wydajności na produkcji.

Sprawdź Core Web Vitals, gdy API jest pod obciążeniem

Dział zatytułowany „Sprawdź Core Web Vitals, gdy API jest pod obciążeniem”

p95 serwera może wyglądać dobrze, a strona nadal działa wolno, bo przeglądarka czeka na pracę, której API nie widzi. Mierz front-end w trakcie testu obciążenia, a nie na bezczynnym stagingu.

Ślad laboratoryjny nie mierzy INP, bo ta metryka wymaga prawdziwej interakcji użytkownika. INP bierz z danych terenowych w narzędziu RUM lub analitycznym, a tej kontroli używaj do LCP i przesunięć układu pod obciążeniem. Funkcjonalne testy w przeglądarce opisuje strona automatyzacja testów end-to-end.

Dwie bramki łapią dwa różne rodzaje problemów i potrzebujesz obu.

Bramka bezwzględna to thresholds w skrypcie. k6 run kończy się niezerowym kodem, gdy dowolny próg nie przejdzie, więc krokiem CI jest sam przebieg. Bramka względna łapie to, czego progi nie widzą: zmiana, która podwaja p95 z 90 ms do 180 ms, nadal przechodzi p(95)<300, choć zjada połowę zapasu. Do tego potrzebujesz zapisanej linii bazowej i porównania.

Workflow, który powinien powstać z tego promptu, wygląda tak. Testuje build z pull requesta uruchomiony na runnerze, więc wynik dotyczy właśnie tej zmiany:

.github/workflows/perf.yml
name: perf
on: pull_request
permissions:
contents: read
jobs:
smoke:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: grafana/setup-k6-action@v1
- run: docker compose up -d --wait
- run: k6 run tests/perf/smoke.js
env:
BASE_URL: http://localhost:3000
- run: node scripts/perf-compare.mjs perf/baseline.json summary.json

Powyższy workflow pokazuje jeden przebieg; prompt prosi o medianę z trzech, która tłumi szum runnera. Agent pisze bramkę, ale w samej bramce nie ma agenta. Dlatego werdykt jest powtarzalny: ten sam commit daje ten sam wynik i nikt nie musi czytać skryptu, żeby ufać czerwonemu lub zielonemu statusowi.

Dwie zasady odpowiedzialności sprawiają, że bramce można ufać:

  • Objęcie perf/baseline.json i bloków thresholds regułą CODEOWNERS dla lidera technicznego. Agent poproszony o „zazielenienie CI” może poluzować próg albo odświeżyć linię bazową; wymagana recenzja zamienia to w widoczną decyzję. Tak samo obejmij scripts/perf-compare.mjs i .github/workflows/perf.yml i włącz „Require review from Code Owners”: przy pull_request zadanie uruchamia kopie obu plików z pull requesta, więc niezrecenzowana zmiana mogłaby sprawić, że porównanie zawsze kończy się kodem 0. Szerzej opisuje ten wzorzec strona ochrona wyroczni.
  • Podział przebiegów według kosztu. Trzydziestosekundowy test dymny działa na każdym pull requeście. Pełny test obciążenia na stagingu działa co noc na main z zaplanowanego workflow, z tokenem stagingu o minimalnych uprawnieniach z magazynu sekretów. Test stresu działa raz w tygodniu i przed premierami. Wpięcie tego w pipeline opisuje strona pipeline’y CI/CD.

Kiedy liczby z testów obciążenia wprowadzają w błąd

Dział zatytułowany „Kiedy liczby z testów obciążenia wprowadzają w błąd”

Gdy wynik wygląda na niemożliwy, przekaż agentowi pełne podsumowanie k6 i metryki zasobów generatora i poproś, żeby rozstrzygnął, czy to prawdziwe wąskie gardło serwera, czy artefakt testu, zanim eskalujesz problem.