CodeWorlds
Powrót do kolekcji
Przewodnik18 min czytaniaZespół CodeWorlds

k6, testy obciążeniowe pisane w JavaScripcie

k6 generuje ruch silnikiem w Go, a scenariusz piszesz w JavaScripcie. Wersja 2.2.0, licencja AGPL-3.0, moduł browser i cennik Grafana Cloud k6.

k6, testy obciążeniowe pisane w JavaScripcie

k6 to program napisany w Go, który generuje ruch według scenariusza zapisanego w JavaScripcie i zbiera z niego metryki. Bieżące wydanie gałęzi drugiej to 2.2.0 z 10 sierpnia 2026 roku, repozytorium grafana/k6 ma około 31,3 tysiąca gwiazdek, a licencja to AGPL-3.0 w wersji dosłownej, bez dopisanego wyjątku dla łączenia z innym kodem.

Co k6 mierzy, a czego nie mierzy

Najczęstsze nieporozumienie wokół k6 bierze się stąd, że scenariusz wygląda jak test end to end, a robi coś zupełnie innego. Test end to end sprawdza, czy funkcja działa: klika w przycisk, czeka na element, porównuje tekst. Test obciążeniowy sprawdza, jak zachowuje się system, kiedy tę samą operację wykonuje jednocześnie kilkuset użytkowników. Pierwszy odpowiada na pytanie „czy to w ogóle działa", drugi na pytanie „przy jakim natężeniu przestaje działać".

k6 należy do drugiej kategorii i konsekwencje tego widać w architekturze. Domyślnie żadna przeglądarka nie jest uruchamiana. k6 wysyła żądania HTTP prosto z Go, więc nie ma DOM, nie ma CSS, nie ma wykonywania skryptów po stronie klienta i nie ma pomiaru czasu renderowania. To, co mierzysz, to czas odpowiedzi zaplecza: kolejkowanie połączeń, uzgadnianie TLS, czas oczekiwania na pierwszy bajt, czas pobierania treści. Jeżeli Twoja aplikacja zwalnia przez ciężki pakiet JavaScriptu w przeglądarce, k6 uruchomiony w trybie protokołu tego nie zobaczy.

JavaScript pełni tu rolę języka opisu scenariusza, a nie środowiska wykonania. Skrypt działa w Sobek, czyli interpreterze ECMAScriptu napisanym w Go, a nie w Node. Każdy wirtualny użytkownik dostaje osobną instancję tego interpretera uruchamianą w goroutynie, dzięki czemu jedna maszyna utrzymuje tysiące równoległych sesji bez kosztu tysięcy procesów. Cena za to jest konkretna: nie masz dostępu do wbudowanych modułów Node, nie zaimportujesz dowolnego pakietu z npm w czasie działania testu, a wszystko, czego potrzebujesz z ekosystemu npm, musisz wcześniej spakować bundlerem do pojedynczego pliku.

Od wersji 0.57 pliki z rozszerzeniem .ts są obsługiwane domyślnie. k6 przepuszcza je przez esbuild, który usuwa adnotacje typów. To jest usuwanie, nie sprawdzanie: błąd typu w scenariuszu nie zatrzyma uruchomienia. Jeśli zależy Ci na weryfikacji, tsc --noEmit musi zostać w potoku osobno, tak samo jak w każdym innym projekcie na TypeScripcie. Tryb zgodności ustawia się flagą --compatibility-mode albo zmienną K6_COMPATIBILITY_MODE, a domyślna wartość extended różni się od base tylko tym, że dodaje aliasowanie zmiennej global na globalThis dla kodu przeniesionego z Node.

Z tego podziału wynika praktyczna reguła doboru narzędzia. Jeżeli pytanie brzmi „czy ta funkcja nadal działa po ostatniej zmianie", odpowiedź leży poza k6. Jeżeli pytanie brzmi „ile jednoczesnych sesji obsłuży ta końcówka, zanim dziewięćdziesiąty piąty percentyl przekroczy pół sekundy", k6 jest dokładnie tym, czego szukasz. Oba rodzaje testów bywają uruchamiane w tym samym potoku, ale mierzą różne rzeczy i mylenie ich prowadzi do wniosków, których nie da się obronić.

Wersja, licencja i stan projektu

Numeracja wydań wymaga chwili uwagi, bo dwie gałęzie są utrzymywane równolegle. Wersja 2.0.0 ukazała się 11 maja 2026 roku, 2.1.0 pod koniec czerwca, a 2.2.0 dziesiątego sierpnia. Dwa dni po 2.2.0, dwunastego sierpnia, wyszła jeszcze wersja 1.8.1, czyli poprawka do starszej linii. Jeśli sprawdzasz najnowsze wydanie po dacie, dostaniesz 1.8.1 i wyciągniesz błędny wniosek, że projekt cofnął się o wersję główną.

Przejście na dwójkę było czyszczeniem długu. Ścieżka modułu Go zmieniła się z go.k6.io/k6 na go.k6.io/k6/v2, co wymusza zmianę importów w każdym rozszerzeniu. Zniknęły polecenia k6 login, k6 pause, k6 resume, k6 scale i k6 status, razem z executorem externally-controlled, na którym się opierały, i bez zamiennika. Usunięto flagi --no-summary oraz --upload-only, wsparcie dla options.ext.loadimpact zastąpione zostało przez options.cloud, moduł k6/experimental/redis wypadł, a pozycyjna forma k6 cloud script.js ustąpiła miejsca k6 cloud run script.js. Serwer HTTP z interfejsem sterującym nie startuje już domyślnie i trzeba go włączyć flagą --address. Biblioteka web-vitals została podniesiona do 5.1.0, przez co zniknęła wycofana metryka FID.

Licencja to punkt, który trzeba przeczytać dokładnie, zanim k6 wejdzie do firmowego repozytorium. Trzy źródła mówią to samo i żadne nie zawiera wyjątku. Plik LICENSE.md w gałęzi głównej to sześćset sześćdziesiąt linii dosłownego tekstu GNU Affero General Public License w wersji 3, bez dopisanej sekcji z dodatkowym pozwoleniem na łączenie. Plik README.md stwierdza wprost, że k6 jest rozpowszechniane na licencji AGPL-3.0. Interfejs programistyczny GitHuba raportuje dla repozytorium ten sam identyfikator. To rzadki przypadek pełnej zgodności, tylko że zgodność dotyczy licencji o najsilniejszym efekcie zaraźliwym spośród popularnych licencji otwartych.

Praktycznie oznacza to trzy rzeczy. Uruchamianie k6 jako narzędzia w potoku ciągłej integracji nie rodzi żadnych obowiązków, bo AGPL wiąże dystrybucję i udostępnianie przez sieć, a nie samo używanie programu. Zbudowanie własnego binarium k6 z rozszerzeniami i rozdanie go poza organizację jest już dystrybucją utworu pochodnego, więc kod rozszerzeń musi być dostępny na warunkach AGPL. Wystawienie usługi, w której cudzy użytkownik przez sieć steruje Twoją zmodyfikowaną wersją k6, uruchamia sekcję trzynastą i obowiązek udostępnienia źródeł temu użytkownikowi.

Dwie rzeczy dookoła k6 mają licencje inne niż rdzeń i łatwo je pomylić z licencją samego narzędzia. Pakiet @types/k6 pochodzi z DefinitelyTyped, ma wersję 2.2.0 z 17 sierpnia 2026 roku i licencję MIT. To wyłącznie deklaracje typów, więc dopisanie ich do devDependencies nie wciąga do projektu niczego copyleftowego. Narzędzie do budowania własnych binariów, grafana/xk6, jest na Apache 2.0, i to bywa źródłem błędnego wniosku, że rozszerzenia da się trzymać na licencji permisywnej. Apache 2.0 obejmuje sam builder, a nie wynik jego pracy. Same rozszerzenia mają zresztą licencje mieszane: grafana/xk6-dashboard i grafana/xk6-faker są na AGPL-3.0, a grafana/xk6-sql na Apache 2.0.

Jest jeszcze rozjazd w dystrybucji, który znajdzie każdy audyt. Pakiet k6 w rejestrze npm to atrapa. Ma numer 0.0.0, został opublikowany 13 czerwca 2017 roku, opisuje się jako „Dummy package for autocompleting k6 scripts", deklaruje w polu license wartość AGPL-3.0, a po rozpakowaniu archiwum zawiera dokładnie jeden plik, package.json. Nie ma tam ani kodu, ani tekstu licencji. Podobnie wygląda oficjalne archiwum z binarium: k6-v2.2.0-linux-amd64.tar.gz waży około trzydziestu megabajtów i po rozpakowaniu daje katalog z jednym plikiem wykonywalnym. Pliku licencyjnego w środku nie ma, mimo że AGPL wymaga dołączenia jej tekstu do przekazywanych kopii. Jeżeli w firmie redystrybuujesz to archiwum wewnętrznie, dołóż do niego LICENSE.md z repozytorium samodzielnie.

Instalacja i pierwszy scenariusz

k6 instaluje się jako pojedyncze binarium, przez menedżer pakietów systemu albo przez obraz kontenera. Instalacja przez npm nie zadziała z powodu opisanego wyżej.

Code
Bash
# macOS
brew install k6

# Debian i Ubuntu, po dodaniu repozytorium Grafany
sudo apt-get install k6

# kontener, bez instalacji w systemie
docker run --rm -i grafana/k6 run - < script.js

# szkielet scenariusza protokolarnego
k6 new script.js

# szkielet scenariusza przeglądarkowego
k6 new --template browser browser-script.js

# uruchomienie z nadpisaniem opcji z linii poleceń
k6 run --vus 50 --duration 30s script.js

# przebieg jednorazowy, bez etapu setup i teardown
k6 run --iterations 1 --no-setup --no-teardown script.js

Najprostszy scenariusz mieści się w kilkunastu liniach i pokazuje wszystkie trzy elementy, na których stoi każdy późniejszy test: żądanie, sprawdzenie odpowiedzi i próg decydujący o wyniku.

Code
JavaScript
import http from 'k6/http'
import { check, sleep } from 'k6'

export const options = {
  vus: 50,
  duration: '2m',
  thresholds: {
    http_req_duration: ['p(95)<500', 'p(99)<1200'],
    http_req_failed: ['rate<0.01'],
    checks: ['rate>0.99']
  }
}

export default function () {
  const res = http.get('https://test.k6.io/contacts.php')

  check(res, {
    'status 200': (r) => r.status === 200,
    'treść niepusta': (r) => r.body.length > 0
  })

  sleep(1)
}

Funkcja check nie przerywa iteracji, kiedy warunek nie jest spełniony. Zwiększa tylko licznik metryki checks i idzie dalej, bo test obciążeniowy ma dokończyć pomiar, a nie wywrócić się na pierwszym błędzie. O powodzeniu całego przebiegu decyduje sekcja thresholds: naruszony próg daje niezerowy kod wyjścia, czyli czerwony wynik w potoku. Bez progów k6 run zwróci zero nawet wtedy, gdy połowa żądań zakończyła się piątką z serwera.

Scenariusze, executory i progi

Para vus plus duration wystarcza do pierwszego pomiaru i nie wystarcza do niczego więcej. Prawdziwe scenariusze definiuje się w sekcji scenarios, gdzie każdy wpis wybiera executor, czyli sposób rozłożenia obciążenia w czasie. Executorów jest sześć: shared-iterations, per-vu-iterations, constant-vus, ramping-vus, constant-arrival-rate i ramping-arrival-rate.

Podział przebiega wzdłuż jednej granicy, którą trzeba zrozumieć, żeby wyniki miały sens. Executory oparte na wirtualnych użytkownikach utrzymują stałą liczbę równoległych sesji, więc kiedy serwer zwalnia, liczba żądań na sekundę sama spada i test przestaje mierzyć to, co miał mierzyć. Executory oparte na tempie przybycia utrzymują stałą liczbę iteracji na sekundę niezależnie od czasu odpowiedzi, przydzielając na to pulę wirtualnych użytkowników. Do sprawdzenia, czy usługa wytrzyma trzysta zamówień na minutę, właściwy jest tylko ten drugi wariant.

Code
JavaScript
import http from 'k6/http'
import { Trend, Counter } from 'k6/metrics'
import exec from 'k6/execution'

const checkoutDuration = new Trend('checkout_duration', true)
const checkoutErrors = new Counter('checkout_errors')

export const options = {
  scenarios: {
    przegladanie: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        { duration: '2m', target: 100 },
        { duration: '5m', target: 100 },
        { duration: '2m', target: 0 }
      ],
      gracefulRampDown: '30s',
      tags: { scenariusz: 'przegladanie' }
    },
    zakupy: {
      executor: 'constant-arrival-rate',
      rate: 300,
      timeUnit: '1m',
      duration: '9m',
      preAllocatedVUs: 60,
      maxVUs: 200,
      startTime: '30s',
      exec: 'checkout'
    }
  },
  thresholds: {
    'http_req_duration{scenariusz:przegladanie}': ['p(95)<400'],
    checkout_duration: ['p(95)<900'],
    checkout_errors: ['count<20'],
    dropped_iterations: ['count<1']
  }
}

export default function () {
  http.get('https://test.k6.io/')
}

export function checkout() {
  const res = http.post('https://test.k6.io/login.php', {
    login: `user_${exec.vu.idInTest}`,
    password: 'secret'
  })

  checkoutDuration.add(res.timings.duration)
  if (res.status >= 400) {
    checkoutErrors.add(1)
  }
}

Kilka szczegółów z tego pliku warto rozpisać. Pole exec wskazuje eksportowaną funkcję, więc jeden plik obsługuje wiele niezależnych profili ruchu naraz. Pola preAllocatedVUs i maxVUs są obowiązkowe dla executorów opartych na tempie: k6 rezerwuje pulę z góry, bo tworzenie nowego wirtualnego użytkownika w trakcie testu kosztuje. Metryka dropped_iterations liczy iteracje, których nie udało się rozpocząć na czas z braku wolnych użytkowników, i próg na niej jest najtańszym sposobem wykrycia, że generator ruchu, a nie badany system, był wąskim gardłem. Składnia z klamrą w nazwie progu zawęża go do konkretnej etykiety, dzięki czemu jeden scenariusz nie psuje wyniku drugiemu.

Metryki własne i wyjścia z wynikami

k6 zbiera dwadzieścia kilka metryk wbudowanych. Te używane najczęściej to http_req_duration, czyli pełny czas żądania, http_req_waiting, czyli sam czas oczekiwania na pierwszy bajt, http_req_failed jako współczynnik niepowodzeń, http_reqs jako licznik, iterations i iteration_duration dla przebiegów scenariusza, vus oraz vus_max dla obsady, data_received i data_sent dla wolumenu, a także checks, group_duration i dropped_iterations. Do tego dochodzą metryki http_req_blocked, http_req_connecting i http_req_tls_handshaking, które rozbijają narzut nawiązywania połączenia, oraz grpc_req_duration dla gRPC.

Metryki własne dodaje się przez cztery typy z modułu k6/metrics: Counter do zliczania, Gauge do ostatniej wartości, Rate do proporcji sukcesów i Trend do rozkładu z percentylami. Drugi argument konstruktora Trend ustawia interpretację wartości jako czasu, co zmienia jedynie formatowanie w podsumowaniu.

Code
Bash
# strumień zdarzeń do pliku, każda próbka osobno
k6 run --out json=raw.json script.js

# zapis do bazy szeregów czasowych przez Prometheus remote write
K6_PROMETHEUS_RW_SERVER_URL=http://localhost:9090/api/v1/write \
  k6 run --out experimental-prometheus-remote-write script.js

# eksport przez OpenTelemetry
k6 run --out opentelemetry script.js

# wbudowany panel w przeglądarce plus raport HTML
K6_WEB_DASHBOARD=true K6_WEB_DASHBOARD_EXPORT=report.html k6 run script.js

# zawężenie statystyk w podsumowaniu na wyjściu standardowym
k6 run --summary-trend-stats="min,med,p(95),p(99),max" script.js

Lista wyjść wbudowanych obejmuje json, csv, cloud, influxdb, opentelemetry oraz experimental-prometheus-remote-write, do tego panel webowy sterowany zmiennymi K6_WEB_DASHBOARD, K6_WEB_DASHBOARD_EXPORT, K6_WEB_DASHBOARD_HOST, K6_WEB_DASHBOARD_PORT, K6_WEB_DASHBOARD_OPEN i K6_WEB_DASHBOARD_PERIOD. Dwa wyjścia, które ludzie wciąż pamiętają, już nie istnieją: kafka wypadło w wersji 0.34.0, statsd w 0.55.0, a k6 zamiast działać zwraca komunikat z odnośnikiem do zewnętrznego rozszerzenia. Czego brakuje w tej liście, dobierasz przez xk6, budując własne binarium, i wtedy wracasz do rozważań licencyjnych z poprzedniej sekcji. Do korelacji skoku opóźnień z konkretnym wyjątkiem po stronie aplikacji wygodniej jest zestawić wynik k6 ze zdarzeniami z Sentry niż szukać przyczyny w samych liczbach.

Moduł browser i granica z testem end to end

Wyjątkiem od reguły „k6 nie uruchamia przeglądarki" jest moduł k6/browser, wbudowany w rdzeń i sterujący prawdziwą przeglądarką opartą na Chromium przez Chrome DevTools Protocol. Interfejs jest celowo bliski temu, co oferuje Playwright: browser.newPage, page.goto, page.locator, page.screenshot. Od wersji 0.52.0 całe API jest asynchroniczne, więc niemal każda metoda zwraca obietnicę.

Code
JavaScript
import { browser } from 'k6/browser'
import { check } from 'k6'

export const options = {
  scenarios: {
    ui: {
      executor: 'shared-iterations',
      vus: 5,
      iterations: 20,
      options: {
        browser: { type: 'chromium' }
      }
    }
  },
  thresholds: {
    browser_web_vital_lcp: ['p(95)<2500'],
    browser_web_vital_cls: ['p(95)<0.1'],
    checks: ['rate==1.0']
  }
}

export default async function () {
  const page = await browser.newPage()

  try {
    await page.goto('https://test.k6.io/', { waitUntil: 'networkidle' })
    const naglowek = page.locator('h1')
    check(await naglowek.textContent(), {
      'naglowek widoczny': (t) => t !== null && t.length > 0
    })
  } finally {
    await page.close()
  }
}

Moduł dokłada własne metryki: browser_data_received, browser_data_sent, browser_http_req_duration, browser_http_req_failed oraz zestaw Core Web Vitals w postaci browser_web_vital_lcp, browser_web_vital_fcp, browser_web_vital_cls, browser_web_vital_inp i browser_web_vital_ttfb. Metryka FID zniknęła razem z podniesieniem biblioteki web-vitals w wersji 2.0.0, więc próg na niej po prostu nie zadziała. Zachowanie przeglądarki sterują zmienne K6_BROWSER_HEADLESS, K6_BROWSER_ARGS, K6_BROWSER_EXECUTABLE_PATH, K6_BROWSER_TIMEOUT, K6_BROWSER_IGNORE_DEFAULT_ARGS, K6_BROWSER_DEBUG i K6_BROWSER_TRACES_METADATA. Wersja 2.2.0 dołożyła chromium.connectOverCDP(), które podłącza test do już działającej instancji przeglądarki po adresie WebSocket podanym w czasie działania skryptu.

Skala tego trybu jest zupełnie inna niż w trybie protokołu. Jedna instancja Chromium zjada setki megabajtów pamięci i zauważalny ułamek rdzenia, więc pięciu użytkowników przeglądarkowych bywa cięższych od pięciuset protokolarnych. Sensowny układ to trzymać obciążenie na warstwie protokołu, a równolegle puścić kilku użytkowników przeglądarkowych, żeby zmierzyć, jak Web Vitals reagują na to obciążenie. Do zwykłej regresji funkcjonalnej moduł browser nie jest właściwym narzędziem i tam lepiej sprawdzi się Cypress albo sam Playwright, choćby dlatego, że mają dojrzalsze raportowanie błędów i nagrywanie przebiegów.

Grafana Cloud k6 i cennik

Grafana Cloud k6 to usługa, w której ten sam skrypt uruchamiany jest ze stref obciążenia dostawcy, a wyniki lądują w panelu razem z resztą telemetrii. Polecenia to k6 cloud run script.js oraz k6 cloud run --local-execution script.js, przy czym ten drugi wariant liczy ruch z Twojej maszyny, a do chmury wysyła same wyniki. Od wersji 2.2.0 wysyła też logi, chyba że dołożysz --no-cloud-logs. Wersja 2.0.0 zaostrzyła dwie rzeczy: każde polecenie chmurowe wymaga jawnego wskazania stacka, a przerwanie testu z powodu innego niż naruszony próg zwraca kod wyjścia 97 zamiast dawnego zera.

Rozliczenie idzie w wirtualnych godzinach użytkownika, oznaczanych skrótem VUh. Plan darmowy kosztuje zero i daje pięćset VUh miesięcznie ze wsparciem społecznościowym. Plan Pro w wariancie samoobsługowym ma opłatę platformową dziewiętnaście dolarów miesięcznie, w którą wliczone jest tych samych pięćset VUh, a wszystko powyżej rozlicza się według zużycia. Stawka spada wraz z wolumenem: sto pięćdziesiąt tysięcznych dolara za VUh w przedziale od jednej do trzech i pół tysiąca, sto trzydzieści pięć tysięcznych w przedziale od trzech i pół do siedmiu i pół tysiąca oraz sto dwadzieścia tysięcznych powyżej siedmiu i pół tysiąca. Plan Enterprise nie ma podanej stawki, a jedyna liczba na stronie to minimalne zobowiązanie dwudziestu pięciu tysięcy dolarów rocznie.

Z tego zestawienia wynika rzecz, którą łatwo przeoczyć: limit pięciuset VUh jest identyczny w planie darmowym i w płatnym, więc dziewiętnaście dolarów miesięcznie kupuje wsparcie w trybie osiem godzin przez pięć dni oraz prawo do przekroczenia limitu, a nie większy przydział. Sam przelicznik VUh też bywa mylący, bo nie jest to czas trwania testu ani liczba żądań. Test z pięciuset wirtualnymi użytkownikami trwający dwanaście minut zużywa mniej więcej sto VUh, więc kilkanaście takich przebiegów wyczerpuje pulę darmową w ciągu miesiąca.

Uzależnienie od dostawcy jest tu ograniczone i to jest realna zaleta układu. Skrypt pozostaje zwykłym plikiem JavaScriptu, który działa lokalnie bez żadnego konta, a jedyne, co wiąże go z chmurą, to sekcja options.cloud i wybór stref obciążenia. Wyprowadzenie się polega na skierowaniu wyjścia w inne miejsce i przywróceniu własnych maszyn generujących ruch, na przykład kontenerów na Railway albo węzłów operatora w klastrze.

k6 a alternatywy

Cechak6Apache JMeterGatlingLocustPlaywright
Język scenariuszaJavaScript lub TypeScriptXML z edytorem graficznymScala, Java lub KotlinPythonJavaScript lub TypeScript
Silnik wykonaniaGoJVMJVMPythonNode z przeglądarką
Uruchamia przeglądarkętylko przez moduł browsernienieniezawsze, to jest jej zadanie
Model obciążeniawirtualni użytkownicy oraz tempo przybyciawątkiwirtualni użytkownicyzadania współbieżnebrak, jeden przebieg naraz
LicencjaAGPL-3.0Apache 2.0Apache 2.0MITApache 2.0

Wybór rozstrzyga się szybko. Jeśli zespół pisze w JavaScripcie i chce trzymać testy wydajności w tym samym repozytorium co aplikację, k6 jest naturalnym kandydatem, pod warunkiem zaakceptowania AGPL. Jeśli licencja copyleft jest w firmie wykluczona regulaminowo, zostają Gatling i JMeter na Apache 2.0. Jeśli zaplecze i tak jest w Pythonie, Locust oszczędza jeden język w projekcie. A jeśli tak naprawdę potrzebujesz sprawdzić, czy formularz działa po ostatniej zmianie, to nie jest zadanie dla narzędzia obciążeniowego, tylko dla Playwrighta i dla zestawu testów jednostkowych w Viteście.

Typowe błędy

Pierwszy to test bez progów. Bez sekcji thresholds proces zawsze kończy się kodem zero, więc w potoku ciągłej integracji taki krok świeci na zielono niezależnie od wyników. Minimum sensowne to próg na http_req_failed i jeden percentyl na http_req_duration.

Drugi to mierzenie własnego generatora zamiast badanego systemu. Kiedy maszyna uruchamiająca k6 wysyca rdzeń albo pasmo, rosnące opóźnienia pochodzą z niej, a nie z serwera. Objawem jest niezerowa metryka dropped_iterations oraz płaski wykres przepustowości mimo rosnącej liczby użytkowników. Próg dropped_iterations: ['count<1'] wykrywa to od razu.

Trzeci to trzymanie się constant-vus w sytuacji, w której pytanie brzmi o liczbę żądań na sekundę. Stała liczba użytkowników przy wolniejszych odpowiedziach sama zmniejsza tempo, więc test cicho łagodnieje dokładnie wtedy, kiedy powinien przycisnąć. Wtedy właściwe są constant-arrival-rate albo ramping-arrival-rate.

Czwarty to funkcja asynchroniczna przekazana do check lub group. Wbudowany check odrzuca takie wywołanie z komunikatem odsyłającym do biblioteki k6-utils, dostępnej pod adresem https://jslib.k6.io/k6-utils/1.6.0/index.js, a group po prostu zgłasza błąd. W testach przeglądarkowych, gdzie prawie wszystko jest obietnicą, to jest pierwsza rzecz, o którą się potykasz.

Piąty to traktowanie obsługi TypeScriptu jako sprawdzania typów. esbuild usuwa adnotacje i nie weryfikuje ich, więc niezgodność typów w scenariuszu przejdzie przez k6 run bez słowa.

Szósty to próba zainstalowania k6 przez npm install k6. Ten pakiet to atrapa z 2017 roku bez ani jednej linii kodu, a mimo to trafia do plików package.json w wielu projektach i do raportów z audytu zależności.

Siódmy to porównywanie wyników k6 z odczuciami użytkownika. W trybie protokołu nie ma renderowania, więc http_req_duration na poziomie stu milisekund nie mówi nic o tym, czy strona wydaje się szybka. Do tego służą metryki browser_web_vital_* albo pomiary z prawdziwego ruchu.

Ósmy to pominięcie warstwy danych w analizie. Jeżeli test obciążeniowy pokazuje ogon rozkładu w okolicy sekundy, przyczyna zwykle siedzi w zapytaniu bez indeksu albo w wyczerpanej puli połączeń do PostgreSQL, a nie w samej aplikacji. Bez metryk z bazy zebranych w tym samym oknie czasowym wynik z k6 mówi tylko, że jest wolno.

FAQ

Czy k6 zastąpi testy end to end?

Nie. k6 w trybie protokołu wysyła żądania HTTP bez przeglądarki, więc nie sprawdzi ani widoczności elementu, ani działania skryptu po stronie klienta. Moduł k6/browser steruje prawdziwym Chromium i pokrywa część tego zakresu, ale jego celem jest pomiar Core Web Vitals pod obciążeniem, a nie regresja funkcjonalna.

Czy licencja AGPL-3.0 blokuje użycie k6 w firmie zamkniętoźródłowej?

Samo uruchamianie k6 w potoku nie rodzi obowiązków, bo AGPL wiąże dystrybucję i udostępnianie przez sieć. Obowiązki pojawiają się, gdy zbudujesz własne binarium z rozszerzeniami i przekażesz je poza organizację albo wystawisz zmodyfikowaną wersję jako usługę sieciową. Deklaracje typów @types/k6 są osobnym pakietem na MIT.

Ile wirtualnych użytkowników utrzyma jedna maszyna?

W trybie protokołu każdy użytkownik to goroutyna z własną instancją interpretera, więc rząd wielkości to tysiące na przeciętnym serwerze, ograniczone głównie pamięcią i liczbą gniazd. W trybie przeglądarkowym liczba spada do jednostek lub kilkudziesięciu, bo każdy użytkownik to osobna instancja Chromium.

Czy mogę zaimportować w scenariuszu pakiet z npm?

Nie bezpośrednio. Skrypt działa w interpreterze Sobek napisanym w Go, a nie w Node, więc moduły wbudowane Node i pakiety z node_modules nie są dostępne w czasie działania. Zależność trzeba wcześniej spakować bundlerem do jednego pliku albo sięgnąć po gotowe biblioteki z jslib.k6.io.

Czym różni się plan darmowy Grafana Cloud k6 od planu Pro?

Oba dają pięćset wirtualnych godzin użytkownika miesięcznie. Plan Pro dokłada opłatę platformową dziewiętnaście dolarów miesięcznie, wsparcie w trybie osiem godzin przez pięć dni w tygodniu oraz rozliczanie zużycia ponad limit według stawki malejącej z wolumenem. Plan Enterprise wymaga zobowiązania od dwudziestu pięciu tysięcy dolarów rocznie.

Co zmieniło się w wersji 2.0.0 i czy migracja boli?

Ścieżka modułu Go zmieniła się na go.k6.io/k6/v2, co dotyczy autorów rozszerzeń. Ze skryptów zniknęły options.ext.loadimpact, moduł k6/experimental/redis i executor externally-controlled. Z linii poleceń wypadły k6 login, k6 pause, k6 resume, k6 scale, k6 status, --no-summary i --upload-only. Typowy scenariusz protokolarny działa bez zmian.

Dokumentację znajdziesz na stronie Grafany, cennik usługi chmurowej na stronie z planami, a kod źródłowy w repozytorium na GitHubie.

Czytaj dalej

Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie