The powerful, easy-to-use testing framework for JavaScript applications
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
QUnit provides several test variants that allow you to control test execution and handle different testing scenarios.
Standard test execution that runs as part of the normal test suite.
/**
* Define a regular test
* @param {string} testName - Name of the test
* @param {Function} callback - Test callback function
*/
QUnit.test(testName, callback)Usage Example:
QUnit.test("basic math operations", function(assert) {
assert.strictEqual(2 + 2, 4, "addition works");
assert.strictEqual(5 * 3, 15, "multiplication works");
});Skip test execution entirely. Useful for temporarily disabling tests without removing them.
/**
* Skip a test (will not execute)
* @param {string} testName - Name of the test
* @param {Function} [callback] - Test callback (optional for skip)
*/
QUnit.skip(testName, callback)Usage Example:
QUnit.skip("broken feature test", function(assert) {
// This test will be skipped and not executed
assert.ok(brokenFeature(), "this won't run");
});Run only specific tests, ignoring all others. Useful for focusing on specific functionality during development.
/**
* Run only this test (ignores all other tests)
* @param {string} testName - Name of the test
* @param {Function} callback - Test callback function
*/
QUnit.only(testName, callback)Usage Example:
QUnit.only("focused test", function(assert) {
// Only this test will run, all others will be ignored
assert.ok(true, "this is the only test that runs");
});
QUnit.test("ignored test", function(assert) {
// This test will be ignored when QUnit.only is used above
assert.ok(false, "this won't run");
});Tests that are expected to fail. These represent features not yet implemented or known bugs that need to be fixed.
/**
* Define a todo test (expected to fail)
* @param {string} testName - Name of the test
* @param {Function} callback - Test callback function
*/
QUnit.todo(testName, callback)Usage Example:
QUnit.todo("implement new feature", function(assert) {
// This test is expected to fail until the feature is implemented
assert.strictEqual(newFeature(), "expected result", "feature not implemented yet");
});Standard module definition that groups related tests together.
/**
* Define a regular module
* @param {string} name - Module name
* @param {Function} [scope] - Module scope function
*/
QUnit.module(name, scope)
/**
* Define a module with options
* @param {string} name - Module name
* @param {Object} options - Module configuration
* @param {Function} [scope] - Module scope function
*/
QUnit.module(name, options, scope)Usage Example:
QUnit.module("User Management", function() {
QUnit.test("create user", function(assert) {
assert.ok(createUser({name: "Alice"}), "user created");
});
QUnit.test("delete user", function(assert) {
assert.ok(deleteUser("alice"), "user deleted");
});
});Skip an entire module and all its tests.
/**
* Skip an entire module
* @param {string} name - Module name
* @param {Object} [options] - Module configuration
* @param {Function} [scope] - Module scope function
*/
QUnit.module.skip(name, options, scope)Usage Example:
QUnit.module.skip("Broken Features", function() {
QUnit.test("broken test 1", function(assert) {
// This entire module is skipped
assert.ok(false);
});
QUnit.test("broken test 2", function(assert) {
// This test is also skipped
assert.ok(false);
});
});Run only tests in this module, ignoring all other modules and tests.
/**
* Run only this module (ignores all other modules)
* @param {string} name - Module name
* @param {Object} [options] - Module configuration
* @param {Function} [scope] - Module scope function
*/
QUnit.module.only(name, options, scope)Usage Example:
QUnit.module.only("Focus Module", function() {
QUnit.test("focused test 1", function(assert) {
assert.ok(true, "this runs");
});
QUnit.test("focused test 2", function(assert) {
assert.ok(true, "this also runs");
});
});
QUnit.module("Other Module", function() {
QUnit.test("ignored test", function(assert) {
// This entire module is ignored
assert.ok(false);
});
});Modules where all tests are expected to fail, representing incomplete features.
/**
* Define a todo module (all tests expected to fail)
* @param {string} name - Module name
* @param {Object} [options] - Module configuration
* @param {Function} [scope] - Module scope function
*/
QUnit.module.todo(name, options, scope)Usage Example:
QUnit.module.todo("Future Features", function() {
QUnit.test("feature A", function(assert) {
// Expected to fail until implemented
assert.strictEqual(featureA(), "working", "not implemented");
});
QUnit.test("feature B", function(assert) {
// Also expected to fail
assert.ok(featureB(), "not implemented");
});
});Run the same test logic with multiple data sets.
/**
* Run test with multiple data sets
* @param {string} testName - Base test name
* @param {Array|Object} dataset - Data to iterate over
* @param {Function} callback - Test callback function
*/
QUnit.test.each(testName, dataset, callback)Usage Example:
const mathData = [
[2, 3, 5],
[5, 7, 12],
[10, -3, 7]
];
QUnit.test.each("addition", mathData, function(assert, [a, b, expected]) {
assert.strictEqual(a + b, expected, `${a} + ${b} = ${expected}`);
});
// Object dataset
const userRoles = {
admin: { role: 'admin', canDelete: true },
user: { role: 'user', canDelete: false },
guest: { role: 'guest', canDelete: false }
};
QUnit.test.each("user permissions", userRoles, function(assert, userData) {
assert.strictEqual(
checkDeletePermission(userData),
userData.canDelete,
`${userData.role} delete permission`
);
});Run tests conditionally based on runtime conditions.
/**
* Run test conditionally
* @param {string} testName - Name of the test
* @param {boolean} condition - Whether to run the test
* @param {Function} callback - Test callback function
*/
QUnit.test.if(testName, condition, callback)Usage Example:
const hasFeatureFlag = process.env.FEATURE_X === 'enabled';
QUnit.test.if("feature X test", hasFeatureFlag, function(assert) {
assert.ok(featureX(), "feature X works");
});
// Browser-specific tests
const isChrome = navigator.userAgent.includes('Chrome');
QUnit.test.if("Chrome-specific feature", isChrome, function(assert) {
assert.ok(chromeSpecificAPI(), "Chrome API available");
});You can combine test flavors with parametrization:
// Todo test with multiple data sets
QUnit.test.todo.each("unimplemented feature", testData, function(assert, data) {
assert.strictEqual(unimplementedFeature(data), data.expected);
});
// Skip test with multiple data sets
QUnit.test.skip.each("temporarily disabled", testData, function(assert, data) {
// These tests are skipped
});
// Only run specific parametrized tests
QUnit.test.only.each("debug specific cases", debugData, function(assert, data) {
// Only these parametrized tests will run
});Use skip temporarily: Use QUnit.skip() for temporarily disabling tests, but don't commit skipped tests to version control without good reason.
Use only for debugging: QUnit.only() is great for focusing on specific tests during development, but remove it before committing.
Document todo tests: Always include clear comments explaining what needs to be implemented for todo tests to pass.
Organize with modules: Group related tests using modules, and use module flavors to control entire feature sets.
Parametrize similar tests: Use test.each() when you have the same test logic but different input data.
Conditional tests for environments: Use test.if() for environment-specific or feature-flag controlled tests.
Install with Tessl CLI
npx tessl i tessl/npm-qunit