k6 Test Maintenance
Maintain, fix, and improve existing k6 test scripts. Five maintenance tasks,
each with a step-by-step procedure in references/workflows.md [blocked]:
- Threshold tightening -- adjust threshold values based on observed metrics
- Version migration -- update scripts for new k6 releases
- Service change adaptation -- fix tests when the underlying service changes
- Refactoring -- clean up and modernize test code
- Best practices audit -- check scripts against current k6 best practices
Core principle: behavior-aware change control
Classify every proposed change by whether it alters the test's runtime behavior:
- Syntactic (behavior unchanged): the k6 runtime produces identical metrics,
pass/fail results, and endpoints. Examples: rename a variable,
let→const, remove unused imports, update comments, reformat. Apply directly. - Behavioral (behavior differs): anything affecting metrics, pass/fail,
timing, request targets, or load shape. Examples: threshold value changes,
adding
sleep(), endpoint URL updates, check rewrites, scenario changes, new thresholds. Always present as a diff with rationale and require confirmation.
The threshold for "behavioral" is deliberately low. If in doubt, treat it as behavioral and ask -- a trivial-looking threshold change can cascade to CI gates, SLO calculations, and alerting.
Dependencies
k6-manage-- fetch and edit GCk6-hosted scripts safely (§5: GET, backup, edit, validate, PUT, verify by sha256). Read it before touching any cloud-hosted script.gcx-- sole tool for Grafana Cloud API access.- mcp-k6 tools --
validate_scriptandget_documentation. Check availability first; fall back tok6 x docsif absent. k6 x docsCLI -- documentation lookup when mcp-k6 isn't configured.k6CLI -- local validation (k6 inspect,k6 run).
Validation loop (every edit)
Every workflow produces a modified script. Never present or PUT an unvalidated script -- run this loop, fixing and re-running until it passes:
- Parse-check:
k6 inspect <script>-- catches syntax errors, invalid options, broken imports. Works on all types including browser tests (no browser needed). If mcp-k6 is available, also runvalidate_script. - Local smoke (non-browser, service reachable):
k6 run --vus 1 --iterations 1 <script>. - Classify the change (below) and verify per the matrix -- recipes in
references/verification.md[blocked]. - Cloud-hosted scripts: apply via the k6-manage §5 safe-edit recipe
(GET → backup → edit → validate → PUT as
application/octet-stream→ sha256-verify).
Change classification
- Class A -- declarative-config only. The diff is confined to
options.thresholdsor similar declarative fields that don't alter what the k6 runtime executes; the bytes insidedefault function, imported modules, and check predicates are byte-identical. Example:p(95)<500→p(95)<420. - Class B -- runtime logic changes. Any change to
default function, imports, helper modules, request URLs, check predicates, or toscenarios.*.vus/iterations/duration/executor(which alter load shape and metric distributions). Example: changing a URL, adding a check, rewriting auth, switching executors.
When in doubt, treat as Class B.
Verification matrix
Verification depth depends on the change class, not the test's duration -- most
edits don't need a full run, and production tests may run for hours. Per-class
recipes (Class A prediction table, Class B short/long, edge cases like scenario
changes and loosening) are in
references/verification.md [blocked].
Documentation lookup
Before proposing any change that touches k6 APIs, imports, or patterns, confirm it against current docs and cite the source in your report -- this grounds recommendations in the real API, not stale model knowledge. Look up in order:
- mcp-k6 (preferred):
get_documentation("best_practices"),get_documentation("javascript-api/k6-browser"),validate_script(...). k6 x docsCLI (always available): 2-call strategy: try the direct path first; if it returns a topic list, pick the subtopic and call again. Full parent paths required (using-k6 thresholds, notthresholds).k6 x docsserves docs for the installed k6 version -- it may lag the target version when migrating.- Web fetch (last resort):
https://grafana.com/docs/k6/latest/.
Async check pattern
A common browser-test bug: using check() from k6 with async predicates. The
built-in check() does not await Promises, so
check(page, { 'title': p => p.locator('h1').textContent() === 'Foo' }) silently
passes because the Promise object is truthy. Two valid fixes:
- Async-aware check from jslib:
import { check } from 'https://jslib.k6.io/k6-utils/1.5.0/index.js'-- then predicates can beasyncandawaitinside them works. - Resolve the value before the check:
const text = await page.locator('h1').textContent(); check(text, { ... })-- keeps the standard synccheckfromk6.
When you hit this during any workflow (migration, refactor, audit), flag it as a behavioral bug and propose one of these fixes.
Script sources
- GCk6-hosted -- fetched and pushed via
k6-manage§5 (GET → backup → edit → validate → PUT → verify sha256). - Local on disk -- read and edit directly. Validate before presenting.
Determine the source before starting: a GCk6 test URL or ID is cloud-hosted; a file path is local.
Workflows
Full procedures are in references/workflows.md [blocked]:
- Threshold tightening [blocked] -- propose values with observed-metric justification, diff, apply, Class A verify.
- Version migration [blocked] -- find deprecated/renamed APIs, classify syntactic vs behavioral, apply, Class B verify.
- Service change adaptation [blocked] -- map each service change to a script change, propose fixes, Class B verify.
- Refactoring [blocked] -- find issues, auto-apply syntactic, propose behavioral, Class B verify after confirmation.
- Best practices audit [blocked] -- doc-driven audit across thresholds, load design, resource management, code quality, and browser specifics.
All five follow behavior-aware change control: auto-apply syntactic changes, present behavioral ones as diffs for confirmation.
Gotchas
References
references/workflows.md[blocked] -- step-by-step procedures for the five maintenance tasksreferences/verification.md[blocked] -- per-class post-edit verification recipes


