Jest Performance Tracker: Measuring Test Execution Time
You're tasked with enhancing your Jest test suite by implementing performance tracking. This challenge will help you understand how to measure and report the execution time of individual tests and test suites, which is crucial for identifying performance bottlenecks and optimizing your development workflow.
Problem Description
The goal is to create a custom Jest reporter that logs the execution time of each test case and each test suite. This reporter should output the results in a human-readable format, allowing developers to quickly see which tests are taking the longest to run.
Key Requirements:
- Individual Test Timing: Measure and report the duration of each
itortestblock. - Suite Timing: Measure and report the total duration of each
describeblock. - Custom Reporter: Implement a Jest custom reporter.
- Output Format: The output should be clear and easy to parse, indicating the test/suite name and its execution time.
- Integration: Demonstrate how to configure Jest to use this custom reporter.
Expected Behavior:
When Jest runs with your custom reporter enabled, it should print logs to the console (or a designated output) for each executed test and suite, showing their respective durations. For example:
Test: 'should perform basic addition' - Duration: 15ms
Suite: 'Math Utilities' - Duration: 120ms
Edge Cases:
- Tests that throw errors should still have their execution time recorded.
- Asynchronous tests (using
async/awaitor callbacks) should have their full execution time measured correctly. - Empty test suites should be handled gracefully (no timing information, or a minimal duration).
Examples
Example 1:
Jest Configuration (jest.config.js):
module.exports = {
reporters: ['<rootDir>/path/to/your/PerformanceReporter.js'],
};
Test File (math.test.ts):
describe('Math Utilities', () => {
test('should perform basic addition', () => {
// Simulate some work
const a = 1;
const b = 2;
expect(a + b).toBe(3);
});
test('should perform basic subtraction', async () => {
// Simulate some asynchronous work
await new Promise(resolve => setTimeout(resolve, 50));
const a = 5;
const b = 3;
expect(a - b).toBe(2);
});
});
Expected Output (from PerformanceReporter):
Suite: 'Math Utilities' - Duration: ~70ms (approximate, will vary)
Test: 'should perform basic addition' - Duration: ~5ms
Test: 'should perform basic subtraction' - Duration: ~55ms
Explanation: The reporter intercepts Jest's events, records the start and end times for each test and suite, calculates the difference, and logs it.
Example 2: Nested Suites
Test File (complex.test.ts):
describe('Outer Suite', () => {
describe('Inner Suite A', () => {
test('test 1', () => { /* ... */ });
test('test 2', () => { /* ... */ });
});
describe('Inner Suite B', () => {
test('test 3', () => { /* ... */ });
});
});
Expected Output (from PerformanceReporter):
Suite: 'Outer Suite' - Duration: <Total Duration>
Suite: 'Inner Suite A' - Duration: <Duration A>
Test: 'test 1' - Duration: <Duration 1>
Test: 'test 2' - Duration: <Duration 2>
Suite: 'Inner Suite B' - Duration: <Duration B>
Test: 'test 3' - Duration: <Duration 3>
Explanation: The reporter should correctly report timings for nested suites as well.
Constraints
- Language: TypeScript.
- Jest Version: Assumed to be Jest v27 or later.
- Node.js Environment: The reporter will run in a Node.js environment.
- Output Method: Console logging (
console.log) is acceptable for this challenge. - No External Libraries (for core logic): The timing mechanism should be implemented using native JavaScript/TypeScript features (e.g.,
performance.now()orDate.now()). You can use Jest's built-in reporter interfaces.
Notes
- Jest provides a rich API for custom reporters. Familiarize yourself with the
JestReporterinterface and its methods likeonTestStart,onTestResult,onRunComplete, etc. - Consider using
performance.now()for more precise timing measurements compared toDate.now(). - Think about how to handle the different event types emitted by Jest to capture both test and suite durations accurately.
- The output should clearly distinguish between suite durations and individual test durations.