{"id":15340,"library":"japa","title":"Japa Lean Node.js Test Runner","description":"Japa is a lean and fast Node.js test runner designed for both testing applications and for building custom test runners. The current stable version is v10.4.0, with minor and patch releases occurring frequently—typically several times a quarter—and major versions released periodically as breaking changes are introduced. A key differentiator is its minimal core, offering faster boot times compared to alternatives like Mocha or Ava, primarily because it does not ship with its own CLI; tests are executed directly as standard Node.js scripts. Japa supports ES6 async/await syntax, ES modules, test groups with lifecycle hooks, regression tests, and offers an extensible assertion system often utilized via plugins. Its design philosophy emphasizes simplicity and provides the foundational components for highly customized testing environments.","status":"active","version":"4.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/thetutlage/japa","tags":["javascript","test","test-runner","typescript"],"install":[{"cmd":"npm install japa","lang":"bash","label":"npm"},{"cmd":"yarn add japa","lang":"bash","label":"yarn"},{"cmd":"pnpm add japa","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The primary testing function is the default export in ESM. For CommonJS, use `const test = require('japa')`.","wrong":"import { test } from 'japa'","symbol":"test","correct":"import test from 'japa'"},{"note":"The `Test` class is a named export, used for programmatic control over individual test instances, particularly when building custom runners.","wrong":"import Test from 'japa'","symbol":"Test","correct":"import { Test } from 'japa'"},{"note":"The `Runner` class is a named export, essential for orchestrating test execution programmatically and for developing custom test runner workflows.","wrong":"import Runner from 'japa'","symbol":"Runner","correct":"import { Runner } from 'japa'"}],"quickstart":{"code":"import test, { Runner } from 'japa'\nimport { assert } from '@japa/assert' // Japa typically uses plugins for assertions\n\n// Configure Japa to discover test files and use the assertion plugin\ntest.configure({\n  files: ['**/*.spec.ts'], // Adjust glob pattern to your test file naming\n  plugins: [assert()]\n})\n\n// A simple function to be tested\nfunction add(a: number, b: number): number {\n  return a + b\n}\n\n// Basic test demonstrating the main `test` function\ntest('should correctly add two positive numbers', ({ assert }) => {\n  assert.equal(add(2, 3), 5)\n  assert.notEqual(add(1, 1), 3)\n})\n\n// Test group with lifecycle hooks\ntest.group('Complex Operations', (group) => {\n  let result: number // State for the group\n\n  group.beforeEach(() => {\n    // Executed before each test in this group\n    result = 0\n    console.log('  [Group Hook] Resetting result to 0')\n  })\n\n  group.afterEach(() => {\n    // Executed after each test in this group\n    console.log(`  [Group Hook] Current result after test: ${result}`)\n  })\n\n  test('should initialize result to 0', ({ assert }) => {\n    assert.equal(result, 0)\n  })\n\n  test('should allow adding values incrementally', ({ assert }) => {\n    result = add(result, 10)\n    assert.equal(result, 10)\n    result = add(result, 5)\n    assert.equal(result, 15)\n  })\n}).timeout(5000) // Example of a group-level timeout in milliseconds\n\n// Manually run the tests. This is optional if using a global runner setup.\nconst runner = new Runner()\nrunner.run()\n  .then(() => console.log('Tests completed.'))\n  .catch((error) => console.error('Tests failed:', error))","lang":"typescript","description":"This quickstart demonstrates basic Japa tests, organizes them into groups with lifecycle hooks, configures the `@japa/assert` plugin for assertions, and shows how to programmatically run tests."},"warnings":[{"fix":"Review and update custom test reporters to adapt to the new emitter event structure for regression tests.","message":"In v10.0.0, the way regression tests are reported by the emitter changed. This may break custom test reporters that rely on the `test:start` and `test:end` emitter events to determine the state of a test, especially for regression test scenarios.","severity":"breaking","affected_versions":">=10.0.0"},{"fix":"Modify any code accessing test titles from emitter events to use `event.title.original` or `event.title.expanded`.","message":"With v9.0.0, the `title` property within `test:start` and `test:end` events no longer provides a custom `toString` method. Direct access to the test title should now use `event.title.original` or `event.title.expanded` properties.","severity":"breaking","affected_versions":">=9.0.0"},{"fix":"Ensure your project's `package.json` scripts or CI configurations directly invoke test files using `node` or a custom runner built on Japa.","message":"Japa is intentionally minimal and does not ship with a command-line interface (CLI). Tests are executed directly as standard Node.js scripts (e.g., `node test/my-test.spec.js`), which deviates from many other test runners that provide `test` or `run` commands.","severity":"gotcha","affected_versions":"*"},{"fix":"Understand the implications of `bail` mode for your workflow. If full test suite execution is always required, ensure `bail` mode is not enabled. Review specific patch notes for `bail` related fixes if encountering unexpected behavior on versions between 10.0.0 and 10.3.0.","message":"The `bail` mode, introduced in v10.0.0, causes the test runner to exit immediately upon the first failing test. While useful for CI/CD, this can halt entire test suites prematurely. Subsequent versions (v10.1.1, v10.2.0, v10.3.0) included fixes for `bail` mode idempotency and skipping behavior.","severity":"gotcha","affected_versions":">=10.0.0"},{"fix":"Install `@japa/assert` (`npm i -D @japa/assert`) and register it as a plugin in your Japa configuration (e.g., `test.configure({ plugins: [assert()] })`) to enable the `assert` object in your test callbacks.","message":"While Japa includes 'inbuilt assertion library' as a feature, common practice and examples often show the use of `@japa/assert` as a plugin for a more robust and explicit assertion experience. Users expecting a globally available `assert` might be confused.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"For ESM, ensure you use `import test from 'japa'`. For CommonJS, use `const test = require('japa')`.","cause":"The main `test` function was imported incorrectly, often by attempting a named import when it is the default export, or by using CommonJS `require` syntax incorrectly.","error":"TypeError: test is not a function"},{"fix":"Verify that `test` is correctly imported as the primary export of the `japa` package. For ESM: `import test from 'japa'`. For CJS: `const test = require('japa')`.","cause":"The `test` function was not imported correctly, leading to `test.group` being called on an undefined or improperly imported `test` object.","error":"TypeError: Cannot read properties of undefined (reading 'group')"},{"fix":"Optimize the test's execution time, increase the timeout duration using `test.timeout(ms)` or `group.timeout(ms)`, and ensure all asynchronous operations within the test are properly awaited.","cause":"A test or a test group exceeded its configured timeout duration before completing execution, often due to long-running asynchronous operations or infinite loops.","error":"Error: Timeout of 5000ms exceeded for test \"should perform a long running operation\""}],"ecosystem":"npm"}