| layout | page-api | |
|---|---|---|
| title | QUnit.config.testFilter | |
| excerpt | Programmatically filter which tests to run. | |
| groups |
|
|
| version_added | 2.25.0 |
Programmatically filter which tests to run.
| type | `function` or `null` |
|---|---|
| default | `null` |
The testFilter property allows you to implement custom logic for filtering which tests to run at runtime. This is useful for advanced scenarios such as:
- Quarantining flaky tests in CI environments
- Distributing tests across parallel workers
- Loading filter criteria from external sources (APIs, files, etc.)
The callback receives a testInfo object and must return a boolean:
- Return
trueto run the test - Return
falseto skip the test
If the callback throws an error, the error is logged as a warning and the test is skipped.
The testFilter callback runs as part of a layered filtering system:
- Test-level filters run first:
test.only(),test.skip(),test.if() - Programmatic filter runs next:
QUnit.config.testFilter - CLI/URL filters run last:
--filter,--module,--moduleId,--testId
This layering enables:
- Test authors to control test execution via
test.only(),test.skip(),test.if() - Project maintainers to implement dynamic filtering via
testFilter - Developers to manually filter tests via CLI or browser URL parameters
| Property | Type | Description |
|---|---|---|
testId |
string | Internal hash identifier (used by "Rerun" links) |
testName |
string | Name of the test |
module |
string | Name of the parent module |
skip |
boolean | Whether test was already marked to skip |
Use an external quarantine list to skip unstable tests in CI without modifying test code.
const quarantineList = ['flaky network test', 'timing-dependent test'];
QUnit.config.testFilter = function (testInfo) {
if (process.env.CI === 'true') {
const isQuarantined = quarantineList.some(function (pattern) {
return testInfo.testName.indexOf(pattern) !== -1;
});
if (isQuarantined) {
console.log('[QUARANTINE] Skipping: ' + testInfo.testName);
return false;
}
}
return true;
};Distribute tests across multiple workers using deterministic hash-based assignment.
const WORKER_ID = parseInt(process.env.WORKER_ID, 10);
const TOTAL_WORKERS = parseInt(process.env.TOTAL_WORKERS, 10);
QUnit.config.testFilter = function (testInfo) {
let hash = 0;
for (let i = 0; i < testInfo.testId.length; i++) {
const char = testInfo.testId.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash;
}
hash = Math.abs(hash);
// Assign test to worker
const assignedWorker = hash % TOTAL_WORKERS;
return assignedWorker === WORKER_ID;
};const quarantined = ['flaky test'];
QUnit.config.testFilter = function (testInfo) {
// Skip quarantined tests
if (quarantined.some(function (p) { return testInfo.testName.indexOf(p) !== -1; })) {
return false;
}
// Skip slow tests in quick mode
if (process.env.QUICK_RUN && testInfo.testName.indexOf('slow') !== -1) {
return false;
}
// Filter by module if specified
if (process.env.TEST_MODULE && testInfo.module.indexOf(process.env.TEST_MODULE) === -1) {
return false;
}
return true;
};