Jest Test Runtime Tracker
Jest is a powerful testing framework, but understanding how long individual tests take can be crucial for optimizing performance and identifying bottlenecks. This challenge focuses on building a custom Jest reporter that tracks the runtime of each test and provides a summary.
Problem Description
Your task is to create a custom Jest reporter in TypeScript that logs the execution time of each individual test case. The reporter should also provide a summary of the total runtime and the average runtime of the tests.
Key Requirements:
- Individual Test Runtime: Record and display the duration of each
itortestblock. - Total Runtime: Calculate and display the overall execution time for all tests.
- Average Runtime: Calculate and display the average execution time per test.
- Customizable Output: The output should be clear and easy to read, potentially in a console-friendly format.
- Jest Integration: The solution must be implementable as a Jest custom reporter.
Expected Behavior:
When Jest runs with your custom reporter, for each test that completes, it should output information like:
Test 'should do something' completed in 15ms
After all tests have run, it should provide a summary:
Jest Runtime Summary:
Total Tests: 5
Total Runtime: 120ms
Average Runtime: 24ms
Edge Cases to Consider:
- Tests that fail or error out: How should their runtime be handled? (For this challenge, we will consider their runtime as part of the total, even if they fail).
- Asynchronous tests (
async/await): Ensure the runtime accurately reflects the completion of the asynchronous operations.
Examples
Example 1:
Suppose you have a Jest test file (my.test.ts) like this:
describe('Math Operations', () => {
it('should add two numbers', () => {
expect(2 + 2).toBe(4);
});
it('should subtract two numbers', () => {
expect(5 - 3).toBe(2);
});
});
Input (Jest Configuration jest.config.js):
module.exports = {
reporters: [
'default', // Keep the default reporter for standard output
['./dist/runtimeReporter.js', { /* reporter options if any */ }] // Path to your compiled reporter
],
};
Output (from your custom reporter):
Test 'Math Operations should add two numbers' completed in 5ms
Test 'Math Operations should subtract two numbers' completed in 8ms
Jest Runtime Summary:
Total Tests: 2
Total Runtime: 13ms
Average Runtime: 6.5ms
Example 2:
Consider a test file with a slightly longer running asynchronous test:
describe('Async Operations', () => {
it('should fetch data', async () => {
await new Promise(resolve => setTimeout(resolve, 100));
expect(true).toBe(true);
});
it('should process data', () => {
expect([1, 2, 3].length).toBe(3);
});
});
Input (Jest Configuration jest.config.js):
(Same as Example 1)
Output (from your custom reporter):
Test 'Async Operations should fetch data' completed in 102ms
Test 'Async Operations should process data' completed in 3ms
Jest Runtime Summary:
Total Tests: 2
Total Runtime: 105ms
Average Runtime: 52.5ms
Constraints
- The reporter must be written in TypeScript.
- The reporter should leverage Jest's reporter API.
- Runtimes should be reported in milliseconds (ms).
- The solution should be compatible with recent versions of Jest.
Notes
- You will need to create a TypeScript file for your custom reporter.
- Remember to compile your TypeScript code into JavaScript before Jest can use it as a reporter.
- Consider how Jest provides test results. You'll likely be interested in the
testResultsproperty of theStatsobject passed to theonRunCompletemethod, or individualtestResultobjects withinonTestCaseResult. - You'll need to implement the
JestReporterinterface. Look for methods likeonTestResultoronTestCaseResultto capture individual test runtimes andonRunCompletefor the summary. - Think about how to accurately measure the duration of each test.
process.hrtime()orperformance.now()are good candidates for precise timing.