QUnit
QUnit is a widely adopted, powerful, and easy-to-use JavaScript testing framework, providing a clear and efficient API for writing unit and integration tests. Originally developed to test the jQuery library, it has significantly matured into a versatile, standalone solution compatible with modern JavaScript applications across various environments, including Node.js (version 10+) and web browsers. The framework is currently stable at version 2.25.0, with an active release cadence that frequently introduces new features and improvements, often focusing on developer experience and compliance with modern JavaScript ecosystems. A significant upcoming release, 3.0.0-rc1, is already available, introducing native ES module (ESM) distribution, which is automatically utilized by Node.js when using `import` statements, marking a key modernization step for module resolution. QUnit's core philosophy centers on simplicity and clarity, which is evident in its direct assertion style, intuitive modular test organization with `QUnit.module()`, programmatic test filtering capabilities via `QUnit.config.testFilter`, and robust support for both synchronous and complex asynchronous testing patterns. It consistently focuses on clear test reporting and comprehensive TAP compliance, ensuring seamless integration with various Continuous Integration/Continuous Deployment (CI/CD) pipelines and test runners.
Common errors
-
ReferenceError: QUnit is not defined
cause The QUnit library has not been loaded or imported correctly into the JavaScript environment where tests are being run.fixEnsure `qunit` is installed (`npm install qunit`). In Node.js, verify that `import QUnit from 'qunit';` (for ESM, v3+) or `require('qunit');` (for CJS) is at the top of your test runner or test files. In a browser, confirm that the `<script src="qunit.js"></script>` tag is correctly placed before your test scripts in the HTML. -
Assertion Failed: Expected N assertions, but M were run
cause This error occurs when the number of `assert` method calls executed within a test (`M`) does not match the count explicitly specified by `assert.expect(N)`.fixIt is often best to remove `assert.expect()` entirely as it can be brittle and is often unnecessary with modern test practices. If retained, meticulously adjust the `N` value passed to `assert.expect()` to precisely reflect the actual number of `assert` method calls that will execute in the test, keeping in mind the change in behavior for `assert.step()` in v3. -
TypeError: Cannot read properties of undefined (reading 'test')
cause This error indicates that you are attempting to call methods like `QUnit.test()` or `QUnit.module()` on an `undefined` `QUnit` object, which typically means `QUnit` itself was not properly imported or made globally available.fixThis problem shares the same root cause as 'ReferenceError: QUnit is not defined'. Double-check your QUnit import statements (ESM `import` for v3+ Node.js, or CJS `require` for older Node/CJS contexts) or verify script tag inclusion for browser-based testing.
Warnings
- breaking QUnit v3.0 introduces native ES module (ESM) support in Node.js. Projects currently using CommonJS `require()` statements for QUnit will need to adapt to `import` statements or ensure their Node.js environment is configured to handle CommonJS modules explicitly.
- breaking With QUnit v3.0, module context is now passed to `before` and `after` hooks. This changes how inheritance between parent and child modules behaves and addresses previous state leakage issues.
- deprecated The counting behavior of `assert.expect()` when combined with `assert.verifySteps()` is changing. In QUnit v3, `assert.expect()` will no longer implicitly count `assert.step()` calls towards the expected assertion total.
- gotcha Asynchronous tests must explicitly signal their completion using either `assert.async()` with `done()` callbacks or by returning a Promise from the test function. Failure to do so will cause the test to finish prematurely, often resulting in false positives.
Install
-
npm install qunit -
yarn add qunit -
pnpm add qunit
Imports
- QUnit.module
const QUnit = require('qunit'); QUnit.module('My Module', function() { /* ... */ });import QUnit from 'qunit'; QUnit.module('My Module', function() { /* ... */ }); - QUnit.test
const QUnit = require('qunit'); QUnit.test('My Test', function(assert) { /* ... */ });import QUnit from 'qunit'; QUnit.test('My Test', function(assert) { /* ... */ }); - assert
import { assert } from 'qunit';QUnit.test('My Test', function(assert) { assert.equal(1, 1, 'Description'); });
Quickstart
import QUnit from 'qunit';
QUnit.module('Calculator operations', function(hooks) {
let sum;
hooks.beforeEach(function(assert) {
sum = 0;
assert.step('beforeEach hook ran');
});
hooks.afterEach(function(assert) {
assert.step('afterEach hook ran');
});
QUnit.test('should correctly add two numbers', function(assert) {
sum = 5 + 3;
assert.strictEqual(sum, 8, '5 + 3 should be 8');
assert.ok(sum > 0, 'Sum should be positive');
assert.verifySteps(['beforeEach hook ran']); // Verify beforeEach ran before assertions
});
QUnit.test('should handle asynchronous addition', function(assert) {
const done = assert.async();
setTimeout(() => {
sum = 10 + 20;
assert.strictEqual(sum, 30, '10 + 20 should be 30 after async wait');
done();
}, 50);
assert.verifySteps(['beforeEach hook ran']);
});
QUnit.test('should handle zero gracefully', function(assert) {
sum = 0 + 0;
assert.strictEqual(sum, 0, '0 + 0 should be 0');
});
});
// To run this example:
// 1. Install QUnit: `npm install qunit`
// 2. Save the code above as `test.js` in your project.
// 3. Add `"type": "module"` to your `package.json` to enable ESM in Node.js.
// 4. Run your tests from the terminal: `npx qunit test.js`