QUnit Test Runner for Node.js
node-qunit is a specialized test runner designed to integrate the QUnit testing framework with Node.js environments. Currently at version 2.0.2, this package was last published seven years ago and is now considered abandoned. It differentiates itself by running each test file in its own spawned Node.js process, enabling parallel execution for improved performance. It offers both a command-line interface (CLI) and a programmatic API for integrating with build systems. While providing test coverage via Istanbul, its core value proposition was maintaining API compatibility with the browser-based QUnit, allowing for consistent test writing across client and server environments. It aimed for a simplified API, particularly for asynchronous testing, and supported both TDD and BDD styles. Given its abandonment, users should exercise caution or consider more modern alternatives.
Common errors
-
Error: Cannot find module 'qunit'
cause Attempting to install or `require` the `qunit` package when `node-qunit` is intended. `node-qunit` was previously named `qunit` before v1.0.0.fix`npm install node-qunit` and then `require("node-qunit")` in your code. -
ReferenceError: module is not defined
cause Using `module()` directly in a QUnit test file. The global `module` keyword conflicts with Node.js's native `module` object.fixUse `QUnit.module()` instead, as `QUnit` is exposed globally by the test runner for defining test modules. -
SyntaxError: Named export 'testrunner' not found
cause Attempting to import `node-qunit` using ES Module syntax (`import { testrunner } from 'node-qunit'`). The package is CommonJS-only.fixChange the import statement to CommonJS: `const testrunner = require("node-qunit");`. -
RangeError: Maximum call stack size exceeded
cause A synchronous test, or an asynchronous test failing to complete its assertions within the configured `maxBlockDuration` (default 2000ms), causing the child process to be killed.fixReview the test for infinite loops, blocking operations, or long-running async tasks. If the test genuinely needs more time, increase `testrunner.options.maxBlockDuration` or the specific run's `maxBlockDuration`.
Warnings
- breaking Prior to version 1.0.0, this package was published under the name `qunit`. Users upgrading from older versions must change their package dependency from `qunit` to `node-qunit`.
- breaking The `node-qunit` package name was previously used by a different, deprecated project that is now published under the name `qnit`. This can cause confusion if installing based on historical context.
- gotcha When writing QUnit test files for `node-qunit`, the global `module` function is reserved by Node.js. You must use `QUnit.module()` instead to define test modules.
- gotcha This package is CommonJS-only and does not support ES Modules (`import`/`export`) syntax for its own API. Attempting to import `node-qunit` using ESM will result in an error.
- breaking This package is considered abandoned, with its last publish seven years ago (version 2.0.2). It is unlikely to receive further updates, bug fixes, or security patches. Usage in new projects is strongly discouraged.
Install
-
npm install node-qunit -
yarn add node-qunit -
pnpm add node-qunit
Imports
- testrunner
import { testrunner } from 'node-qunit';const testrunner = require("node-qunit"); - QUnit.module
module('My tests', function() { /* ... */ });QUnit.module('My tests', function() { /* ... */ }); - QUnit.test
QUnit.test('My test case', function(assert) { /* ... */ });
Quickstart
const testrunner = require("node-qunit");
const path = require("path");
const fs = require("fs");
// Define a simple code file to be tested
const codeFilePath = path.join(__dirname, "my-code.js");
fs.writeFileSync(codeFilePath, `
module.exports = {
add: (a, b) => a + b,
subtract: (a, b) => a - b
};
`);
// Define a simple test file using QUnit API
const testFilePath = path.join(__dirname, "my-tests.js");
fs.writeFileSync(testFilePath, `
QUnit.module('Calculator', function(hooks) {
hooks.beforeEach(function(assert) {
// Setup code if needed
});
QUnit.test('add function', function(assert) {
const calculator = require('./my-code.js'); // Relative path needed for child process
assert.equal(calculator.add(1, 2), 3, '1 + 2 should be 3');
});
QUnit.test('subtract function', function(assert) {
const calculator = require('./my-code.js');
assert.equal(calculator.subtract(5, 2), 3, '5 - 2 should be 3');
});
});
`);
// Configure and run the tests
testrunner.run({
code: codeFilePath,
tests: testFilePath,
log: {
summary: true,
errors: true,
coverage: false // Assuming no istanbul setup for quickstart
}
}, function(err, report) {
if (err) {
console.error("Test runner encountered an error:", err);
process.exit(1);
}
console.log("Test Report:", JSON.stringify(report, null, 2));
// Cleanup generated files
fs.unlinkSync(codeFilePath);
fs.unlinkSync(testFilePath);
process.exit(report.globalSummary.failed > 0 ? 1 : 0);
});