Skip to content

Commit 47f0e01

Browse files
committed
Docs: Add docs for QUnit.config.testFilter
1 parent 1fdc1a3 commit 47f0e01

1 file changed

Lines changed: 130 additions & 0 deletions

File tree

docs/api/config/testFilter.md

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
---
2+
layout: page-api
3+
title: QUnit.config.testFilter
4+
excerpt: Callback to programmatically filter which tests to run.
5+
groups:
6+
- config
7+
version_added: "2.25.0"
8+
---
9+
10+
Callback to programmatically control which tests to run, and which tests to skip or filter out.
11+
12+
<table>
13+
<tr>
14+
<th>type</th>
15+
<td markdown="span">`function` or `null`</td>
16+
</tr>
17+
<tr>
18+
<th>default</th>
19+
<td markdown="span">`null`</td>
20+
</tr>
21+
</table>
22+
23+
The `QUnit.config.testFilter` callback allows you to implement a custom test filter at runtime. This is useful for advanced scenarios such as:
24+
25+
* Distributing tests across parallel workers
26+
* Loading filter criteria from external sources (APIs, files, etc.)
27+
* Quarantining flaky tests in CI environments
28+
29+
The callback receives a `testInfo` object and must return a boolean:
30+
* Return `true` to run the test
31+
* Return `false` to skip the test
32+
33+
If the callback throws an error, the error is logged as a warning and the test is skipped.
34+
35+
## Filter order
36+
37+
Tests are filtered in a hierarchy of three layers:
38+
39+
1. **Test-level filters** run first: [`test.only()`](../QUnit/test.only.md), [`test.skip()`](../QUnit/test.skip.md), [`test.if()`](../QUnit/test.if.md)
40+
2. **Programmatic filter** runs next: `QUnit.config.testFilter`
41+
3. **CLI/URL filters** run last: [`--filter`](./filter.md), [`--module`](./module.md), [`--moduleId`](./moduleId.md), [`--testId`](./testId.md)
42+
43+
These target three different audiences or contexts:
44+
* Test authors to control test execution via `test.only()`, `test.skip()`, `test.if()`
45+
* Project maintainers to implement dynamic filtering via `QUnit.config.testFilter`
46+
* Developers to manually filter tests via CLI or browser URL parameters
47+
48+
## Parameters
49+
50+
### `testInfo` (object)
51+
52+
| Property | Type | Description |
53+
|----------|------|-------------|
54+
| `testId` | string | Internal hash identifier (used by "Rerun" links)
55+
| `testName` | string | Name of the test
56+
| `module` | string | Name of the parent module
57+
| `skip` | boolean | Whether test was already marked to skip
58+
59+
## See also
60+
61+
* [QUnit.config.filter](./filter.md)
62+
* [QUnit.config.module](./module.md)
63+
* [Flat config](./index.md#flat-preconfig), including `qunit_config_filter` and `qunit_config_module` environment variables
64+
* [QUnit.test.if()](../QUnit/test.if.md)
65+
66+
## Examples
67+
68+
### Quarantine flaky tests
69+
70+
Use an external quarantine list to skip unstable tests in CI without modifying test code.
71+
72+
```js
73+
const flakyDatabase = ['my network test', 'my timing-dependent test'];
74+
75+
QUnit.config.testFilter = function (testInfo) {
76+
if (process.env.CI === 'true') {
77+
const isQuarantined = flakyDatabase.some(function (pattern) {
78+
return testInfo.testName.includes(pattern);
79+
});
80+
if (isQuarantined) {
81+
console.log('[QUARANTINE] Skipping: ' + testInfo.testName);
82+
return false;
83+
}
84+
}
85+
return true;
86+
};
87+
```
88+
89+
### Parallel test sharding
90+
91+
Distribute tests across multiple workers using deterministic hash-based assignment.
92+
93+
```js
94+
const WORKER_ID = parseInt(process.env.WORKER_ID, 10);
95+
const TOTAL_WORKERS = parseInt(process.env.TOTAL_WORKERS, 10);
96+
97+
QUnit.config.testFilter = function (testInfo) {
98+
let hash = 0;
99+
for (let i = 0; i < testInfo.testId.length; i++) {
100+
const char = testInfo.testId.charCodeAt(i);
101+
hash = ((hash << 5) - hash) + char;
102+
hash = hash & hash;
103+
}
104+
hash = Math.abs(hash);
105+
106+
// Assign test to worker
107+
const assignedWorker = hash % TOTAL_WORKERS;
108+
return assignedWorker === WORKER_ID;
109+
};
110+
```
111+
112+
### Combine multiple conditions
113+
114+
```js
115+
const flakyDatabase = ['my network test', 'my timing-dependent test'];
116+
117+
QUnit.config.testFilter = function (testInfo) {
118+
// Skip quarantined tests
119+
if (flakyDatabase.some((pattern) => testInfo.testName.includes(pattern))) {
120+
return false;
121+
}
122+
123+
// Skip slow tests in quick mode
124+
if (process.env.QUICK_RUN && testInfo.testName.includes('slow')) {
125+
return false;
126+
}
127+
128+
return true;
129+
};
130+
```

0 commit comments

Comments
 (0)