0
# Test Discovery
1
2
Jest's test discovery system provides advanced capabilities for finding, filtering, and organizing test files with pattern matching, dependency tracking, and change detection for optimized test runs.
3
4
## Capabilities
5
6
### SearchSource Class
7
8
The SearchSource class is the core component responsible for test file discovery and filtering.
9
10
```typescript { .api }
11
/**
12
* Core class for finding and filtering test files
13
*/
14
class SearchSource {
15
constructor(context: TestContext);
16
17
/**
18
* Determines if a given path is a test file based on configuration
19
* @param path - File path to check
20
* @returns True if the path matches test file patterns
21
*/
22
isTestFilePath(path: string): boolean;
23
24
/**
25
* Finds tests matching the given path patterns
26
* @param testPathPatternsExecutor - Pattern executor for test paths
27
* @returns Search results with matching tests
28
*/
29
findMatchingTests(testPathPatternsExecutor: TestPathPatternsExecutor): SearchResult;
30
31
/**
32
* Finds tests by exact file paths
33
* @param paths - Array of exact file paths
34
* @returns Search results with specified test files
35
*/
36
findTestsByPaths(paths: Array<string>): SearchResult;
37
38
/**
39
* Finds tests related to the given source file paths
40
* @param allPaths - Set of source file paths
41
* @param collectCoverage - Whether to collect coverage information
42
* @returns Promise resolving to search results with related tests
43
*/
44
findRelatedTests(allPaths: Set<string>, collectCoverage: boolean): Promise<SearchResult>;
45
46
/**
47
* Main method to get test paths based on configuration and options
48
* @param globalConfig - Global Jest configuration
49
* @param projectConfig - Project-specific configuration
50
* @param changedFiles - Optional changed files information
51
* @param filter - Optional filter function
52
* @returns Promise resolving to comprehensive search results
53
*/
54
getTestPaths(
55
globalConfig: Config.GlobalConfig,
56
projectConfig: Config.ProjectConfig,
57
changedFiles?: ChangedFiles,
58
filter?: Filter
59
): Promise<SearchResult>;
60
}
61
62
interface SearchResult {
63
noSCM?: boolean;
64
stats?: Stats;
65
collectCoverageFrom?: Set<string>;
66
tests: Array<Test>;
67
total?: number;
68
}
69
70
interface Stats {
71
roots: number;
72
testMatch: number;
73
testPathIgnorePatterns: number;
74
testRegex: number;
75
testPathPatterns?: number;
76
}
77
```
78
79
**Usage Examples:**
80
81
```typescript
82
import { SearchSource } from "jest";
83
84
// Create SearchSource instance
85
const searchSource = new SearchSource(testContext);
86
87
// Find all test files
88
const allTests = await searchSource.getTestPaths(
89
globalConfig,
90
projectConfig
91
);
92
93
console.log(`Found ${allTests.tests.length} test files`);
94
95
// Check if a file is a test file
96
const isTest = searchSource.isTestFilePath("src/__tests__/utils.test.js");
97
console.log(`Is test file: ${isTest}`);
98
99
// Find tests related to changed source files
100
const changedFiles = new Set(["src/utils.js", "src/components/Button.js"]);
101
const relatedTests = await searchSource.findRelatedTests(changedFiles, false);
102
103
console.log(`Found ${relatedTests.tests.length} related tests`);
104
```
105
106
### Test Pattern Matching
107
108
Advanced pattern matching for test file discovery:
109
110
```typescript
111
// Find tests by exact paths
112
const specificTests = searchSource.findTestsByPaths([
113
"src/components/Button.test.js",
114
"src/utils/helpers.test.js"
115
]);
116
117
// Find tests matching patterns (via getTestPaths)
118
const patternTests = await searchSource.getTestPaths(
119
{
120
...globalConfig,
121
testPathPatterns: ["components", "utils"]
122
},
123
projectConfig
124
);
125
```
126
127
### Change Detection Integration
128
129
Optimize test runs by finding tests related to changed files:
130
131
```typescript
132
import { SearchSource } from "jest";
133
134
async function runTestsForChangedFiles(
135
searchSource: SearchSource,
136
changedFiles: string[]
137
) {
138
// Find tests related to changed source files
139
const relatedTests = await searchSource.findRelatedTests(
140
new Set(changedFiles),
141
true // collectCoverage
142
);
143
144
if (relatedTests.tests.length === 0) {
145
console.log("No tests found for changed files");
146
return null;
147
}
148
149
return relatedTests;
150
}
151
152
// Usage with git integration
153
async function findTestsForGitChanges() {
154
const changedFiles = await getChangedFilesFromGit();
155
const relatedTests = await searchSource.findRelatedTests(
156
new Set(changedFiles),
157
false
158
);
159
160
return relatedTests.tests.map(test => test.path);
161
}
162
```
163
164
### Custom Test Discovery Patterns
165
166
Implement custom test discovery logic:
167
168
```typescript
169
import { SearchSource } from "jest";
170
171
class CustomTestDiscovery {
172
constructor(private searchSource: SearchSource) {}
173
174
async findTestsByFeature(featureName: string) {
175
// Find all tests
176
const allTests = await this.searchSource.getTestPaths(
177
globalConfig,
178
projectConfig
179
);
180
181
// Filter by feature directory or naming convention
182
const featureTests = allTests.tests.filter(test =>
183
test.path.includes(`features/${featureName}`) ||
184
test.path.includes(`${featureName}.test.`)
185
);
186
187
return {
188
...allTests,
189
tests: featureTests,
190
total: featureTests.length
191
};
192
}
193
194
async findTestsByTags(tags: string[]) {
195
const allTests = await this.searchSource.getTestPaths(
196
globalConfig,
197
projectConfig
198
);
199
200
// Filter tests based on file content or naming patterns
201
const taggedTests = allTests.tests.filter(test => {
202
const filename = test.path.toLowerCase();
203
return tags.some(tag => filename.includes(tag.toLowerCase()));
204
});
205
206
return {
207
...allTests,
208
tests: taggedTests,
209
total: taggedTests.length
210
};
211
}
212
213
async findSlowTests(thresholdMs: number = 1000) {
214
// This would typically require historical test timing data
215
// Implementation would depend on custom test result storage
216
const allTests = await this.searchSource.getTestPaths(
217
globalConfig,
218
projectConfig
219
);
220
221
// Example: identify tests by naming convention
222
const potentiallySlowTests = allTests.tests.filter(test =>
223
test.path.includes("integration") ||
224
test.path.includes("e2e") ||
225
test.path.includes("slow")
226
);
227
228
return {
229
...allTests,
230
tests: potentiallySlowTests,
231
total: potentiallySlowTests.length
232
};
233
}
234
}
235
```
236
237
### Performance Optimization
238
239
Optimize test discovery for large codebases:
240
241
```typescript
242
async function optimizedTestDiscovery(
243
searchSource: SearchSource,
244
options: {
245
useCache?: boolean;
246
maxFiles?: number;
247
changedFilesOnly?: boolean;
248
} = {}
249
) {
250
if (options.changedFilesOnly) {
251
// Only find tests related to changed files
252
const changedFiles = await getChangedFiles();
253
return searchSource.findRelatedTests(new Set(changedFiles), false);
254
}
255
256
// Get all tests with potential limits
257
const allTests = await searchSource.getTestPaths(
258
globalConfig,
259
projectConfig
260
);
261
262
if (options.maxFiles && allTests.tests.length > options.maxFiles) {
263
// Limit test count for performance
264
const limitedTests = allTests.tests.slice(0, options.maxFiles);
265
console.warn(`Limited to ${options.maxFiles} tests (found ${allTests.tests.length})`);
266
267
return {
268
...allTests,
269
tests: limitedTests,
270
total: limitedTests.length
271
};
272
}
273
274
return allTests;
275
}
276
```
277
278
## Integration with Test Execution
279
280
The SearchSource integrates seamlessly with Jest's test execution pipeline:
281
282
```typescript
283
import { SearchSource, createTestScheduler } from "jest";
284
285
async function discoverAndRunTests() {
286
// 1. Discover tests
287
const searchSource = new SearchSource(testContext);
288
const searchResult = await searchSource.getTestPaths(
289
globalConfig,
290
projectConfig
291
);
292
293
// 2. Create scheduler
294
const scheduler = await createTestScheduler(globalConfig, schedulerContext);
295
296
// 3. Execute discovered tests
297
const results = await scheduler.scheduleTests(
298
searchResult.tests,
299
testWatcher
300
);
301
302
return results;
303
}
304
```
305
306
Jest's test discovery system provides the foundation for intelligent test execution, enabling optimized test runs based on code changes, file patterns, and custom discovery logic.