Hone logo
Hone
Problems

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 it or test block.
  • 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 testResults property of the Stats object passed to the onRunComplete method, or individual testResult objects within onTestCaseResult.
  • You'll need to implement the JestReporter interface. Look for methods like onTestResult or onTestCaseResult to capture individual test runtimes and onRunComplete for the summary.
  • Think about how to accurately measure the duration of each test. process.hrtime() or performance.now() are good candidates for precise timing.
Loading editor...
typescript