Skip to content

k6 check() Assertion Not Failing Test Fix

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about k6 check() assertion not failing test fix. We cover key concepts, practical examples, and best practices.

Your k6 test reports checks passing but the test exits with status 0 even when checks fail — check() does not fail the test by itself. You need thresholds to define pass/fail criteria for the overall test run.

The Problem

import http from 'k6/http';
import { check } from 'k6';

export default function () {
  const res = http.get('https://api.example.com/users');
  check(res, {
    'status is 200': (r) => r.status === 200,
  });
}
     ✓ status is 200
     ✗ status is 200

     checks....................: 50.00% ✓ 500   ✗ 500
     ✓ { test status: 0 }

The test exits with code 0 (success) even though half the checks failed. k6 only reports check statistics — it does not enforce pass/fail thresholds unless configured.

Step-by-Step Fix

1. Add thresholds for check pass rate

import http from 'k6/http';
import { check } from 'k6';

export const options = {
  thresholds: {
    checks: ['rate>0.99'],
  },
};

export default function () {
  const res = http.get('https://api.example.com/users');
  check(res, {
    'status is 200': (r) => r.status === 200,
  });
}

2. Set per-check thresholds

export const options = {
  thresholds: {
    'checks{check:status is 200}': ['rate>0.95'],
    'checks{check:response time < 500ms}': ['rate>0.99'],
  },
};

3. Fail the test manually with abort()

import http from 'k6/http';
import { check, abort } from 'k6';

export default function () {
  const res = http.get('https://api.example.com/users');
  const passed = check(res, {
    'status is 200': (r) => r.status === 200,
  });

  if (!passed) {
    abort('Check failed — stopping test');
  }
}

4. Combine thresholds with abortOnFail

export const options = {
  thresholds: {
    http_req_failed: ['rate<0.01'],
    http_req_duration: ['p(95)<2000'],
  },
  noConnectionReuse: true,
};

export default function () {
  const res = http.get('https://api.example.com/users');
  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time < 300ms': (r) => r.timings.duration < 300,
  });
}

5. View exit code in CI

k6 run script.js
echo "Exit code: $?"

Expected output with thresholds:

     ✗ checks.....................: 99.50% ✓ 995  ✗ 5
     ✗ threshold on checks'rate>0.99' failed

Prevention Tips

  • Always define thresholds for checks in test options
  • Use per-check thresholds for granular pass/fail criteria
  • Use abort() for immediate test termination on critical failures
  • Monitor exit code in CI/CD pipelines
  • Set http_req_failed threshold for basic health validation

Common Mistakes with check fail

  1. Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
  2. Non-exhaustive pattern matches that compile with warnings then crash at runtime
  3. Misunderstanding that String is [Char] with poor performance for large text operations

These mistakes appear frequently in real-world K6 code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### Why doesn't check() fail the test by default?

k6 is designed for load testing, not unit testing. A single failed request in a load test with thousands of requests is normal. check() provides pass/fail statistics while thresholds let you define what constitutes an acceptable failure rate for your specific scenario.

What's the difference between check() and threshold?

check() evaluates a single assertion per VU iteration and reports statistics. thresholds evaluate aggregated metrics (rate, percentiles, count) across the entire test run and determine the final pass/fail exit code. Use checks for debugging and thresholds for CI gating.

Can I use thresholds without check()?

Yes, thresholds work on any built-in or custom metric: http_req_duration, http_req_failed, custom Trend metrics, etc. Checks are optional — they provide human-readable assertion names and per-iteration visibility.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro