# Lab 02: HTTP Testing, Checks & Thresholds Adding Validation and Pass/Fail Criteria
Navigate: [All Slides](../index.html) | [Prev: k6 Fundamentals](../01_k6_Fundamentals/index.html) | [Next: Load Profiles](../03_Load_Profiles_and_Stages/index.html)
## What You'll Learn - How to use `check()` to validate status codes, response times, and body content - How to set pass/fail thresholds on built-in and custom metrics - What threshold failures look like in terminal output and exit codes - How to use environment variables to switch targets without editing scripts - The difference between checks and thresholds
## The Problem: No Validation ```javascript export default function () { http.get('http://localhost:3000/'); sleep(1); } ``` This script runs but doesn't verify: - Was the status code 200? - Did the response arrive quickly? - Does the body contain expected content?
## Enter check(): Response Validation ```javascript import { check } from 'k6'; import http from 'k6/http'; export default function () { const res = http.get('http://localhost:3000/'); check(res, { 'status is 200': (r) => r.status === 200, 'response time < 500ms': (r) => r.timings.duration < 500, 'body contains products': (r) => r.body.includes('products'), }); } ``` Each assertion is a named function returning `true` (pass) or `false` (fail).
## How check() Works ```javascript check(res, { 'status is 200': (r) => r.status === 200, 'response time < 500ms': (r) => r.timings.duration < 500, }); ``` - Each check runs independently - Failures are recorded but **do not stop the test** - k6 tracks pass rate across all iterations - Results appear in the terminal summary
## Check Output in Summary ``` ✓ status is 200 ✓ response time < 500ms ✓ body contains products checks.........................: 100.00% ✓ 150 ✗ 0 ``` The `checks` metric aggregates all check results: - **100.00%** = pass rate - **✓ 150** = number of passing checks - **✗ 0** = number of failing checks
## The Limitation of Checks ```javascript check(res, { 'status is 200': (r) => r.status === 200, }); ``` Even if all checks fail, k6 exits with code `0` (success). **Problem:** CI/CD pipelines can't detect failures without thresholds.
## Enter Thresholds: Pass/Fail Gates ```javascript export const options = { vus: 5, duration: '30s', thresholds: { http_req_duration: ['p(95)<500'], checks: ['rate>0.95'], }, }; ``` Thresholds are evaluated at the end of the test: - If **all** thresholds pass → exit code `0` - If **any** threshold fails → exit code `99`
## Threshold Expression Syntax ```javascript thresholds: { http_req_duration: ['p(95)<500'], checks: ['rate>0.95'], http_req_failed: ['rate<0.01'], } ``` Pattern: `
` | Expression | Meaning | |---|---| | `p(95)<500` | 95th percentile must be under 500ms | | `rate>0.95` | Pass rate must be above 95% | | `avg<200` | Average must be under 200ms |
## Running Against a Healthy Service ```bash k6 run scripts/solutions/lab-02-solution.js ``` Expected output: ``` ✓ checks.........................: 100.00% ✓ 150 ✗ 0 ✓ http_req_duration..............: avg=4ms p(95)=12ms running (30s), 0/5 VUs, 150 complete and 0 interrupted iterations default ✓ [==============================] 5 VUs 30s ``` Green checkmarks indicate all thresholds passed.
## Running Against a Broken Service ```bash k6 run -e BASE_URL=http://localhost:3001 scripts/solutions/lab-02-solution.js ``` Expected output: ``` ✗ checks.........................: 72.00% ✓ 108 ✗ 42 ✗ http_req_duration..............: avg=1.2s p(95)=3.8s ERRO[0031] thresholds on metrics 'checks, http_req_duration' have been breached running (30s), 0/5 VUs, 150 complete and 0 interrupted iterations default ✗ [==============================] 5 VUs 30s ``` Red crosses and an error message indicate threshold failures.
## Exit Codes and CI/CD ```bash k6 run scripts/solutions/lab-02-solution.js echo $? ``` | Exit Code | Meaning | |---|---| | `0` | All thresholds passed | | `99` | One or more thresholds failed | | Other | Script error or runtime issue | Use exit code 99 in CI/CD pipelines to fail builds when performance degrades.
## Using Environment Variables ```javascript const BASE_URL = __ENV.BASE_URL || 'http://localhost:3000'; export default function () { http.get(`${BASE_URL}/`); } ``` Run against different environments: ```bash k6 run -e BASE_URL=http://localhost:3001 script.js k6 run -e BASE_URL=https://staging.example.com script.js ``` No code changes needed.
## Key Takeaways - `check()` validates correctness but **never stops the test** - Thresholds turn k6 into a pass/fail gate for CI/CD pipelines - Exit code `99` specifically means threshold breach - The `checks` metric tracks aggregate pass rate of all check assertions - Use `__ENV` variables to make scripts environment-agnostic - The broken-app is a deliberate failure scenario for testing thresholds
# Lab Complete! Ready to explore load profiles and stages
Navigate: [All Slides](../index.html) | [Prev: k6 Fundamentals](../01_k6_Fundamentals/index.html) | [Next: Load Profiles](../03_Load_Profiles_and_Stages/index.html)