Hone logo
Hone
Problems

Implementing a Custom Jest Test Runner for Enhanced Reporting

Jest is a powerful and popular JavaScript testing framework, but sometimes its default reporting mechanisms aren't sufficient for complex projects or specific needs. This challenge requires you to extend Jest's capabilities by creating a custom test runner that intercepts and modifies test execution and reporting. This is useful for integrating with CI/CD pipelines, generating custom reports, or implementing advanced test orchestration.

Problem Description

Your task is to create a custom Jest test runner in TypeScript. This runner should override the default Jest runner to provide custom logging for each test's lifecycle events (start, success, failure).

What needs to be achieved:

  • Create a custom Jest runner class that extends jest-runner.
  • Intercept test execution to log custom messages.
  • Log when a test starts.
  • Log when a test passes.
  • Log when a test fails.

Key Requirements:

  • The custom runner must be implemented in TypeScript.
  • It should leverage Jest's API to hook into the test execution process.
  • The output messages should be clearly distinguishable from Jest's default output.

Expected Behavior: When Jest is configured to use your custom runner, you should see custom log messages in your console corresponding to each test's start, success, or failure.

Example of expected output for a simple test:

[TEST START] my-test-file.test.ts:10:10 calculateSum should return the correct sum
[TEST SUCCESS] my-test-file.test.ts:10:10 calculateSum should return the correct sum

Edge Cases to Consider:

  • Tests that throw uncaught errors.
  • Asynchronous tests.
  • Tests with multiple assertions that might fail.

Examples

Example 1: A Simple Passing Test

Assume you have a test file math.test.ts with the following content:

// math.test.ts
describe('Calculator', () => {
  test('should add two numbers', () => {
    expect(2 + 2).toBe(4);
  });
});

When run with your custom runner, the expected output would include:

[TEST START] math.test.ts:3:3 should add two numbers
[TEST SUCCESS] math.test.ts:3:3 should add two numbers

Example 2: A Failing Test

Assume you have a test file strings.test.ts with the following content:

// strings.test.ts
describe('String Manipulation', () => {
  test('should reverse a string correctly', () => {
    expect('hello'.split('').reverse().join('')).toBe('olleh');
  });

  test('should fail this test', () => {
    expect(true).toBe(false);
  });
});

When run with your custom runner, the expected output would include:

[TEST START] strings.test.ts:4:3 should reverse a string correctly
[TEST SUCCESS] strings.test.ts:4:3 should reverse a string correctly
[TEST START] strings.test.ts:7:3 should fail this test
[TEST FAILURE] strings.test.ts:7:3 should fail this test (AssertionError: expect(true).toBe(false))

(Note: The exact error message might vary slightly depending on Jest's internal representation of the failure)

Constraints

  • The solution must be implemented in TypeScript.
  • You must use Jest's programmatic API and runner interface.
  • The custom runner should not significantly increase the overall test execution time (beyond the logging itself).
  • You should aim for clear and concise log messages.

Notes

  • You'll likely need to extend Jest's TestRunner class.
  • Familiarize yourself with Jest's runTests method and the Test interface.
  • Consider how to handle different types of test results (passed, failed, pending, todo, etc.).
  • To configure Jest to use your custom runner, you'll need to set the runner option in your jest.config.js (or equivalent).
  • Think about how to access test metadata like file path, test name, and line numbers.
Loading editor...
typescript