Hone logo
Hone
Problems

Jest Assertion Count Tracker

This challenge focuses on enhancing Jest test suites by providing a mechanism to track the number of assertions made within a test case. Knowing the assertion count can be valuable for identifying tests that are too short (potentially lacking thoroughness) or excessively long (potentially overly complex and difficult to maintain). You'll create a Jest utility function that monitors and reports assertion counts.

Problem Description

You need to create a Jest utility function called trackAssertions. This function should wrap a test case and record the number of assertions made within that test case. The utility function should accept a test description (string) and a test function as arguments. After the test function completes, trackAssertions should log the number of assertions made to the console, prefixed with the test description.

Key Requirements:

  • The utility function must correctly count assertions made within the provided test function.
  • The utility function must log the assertion count to the console after the test function completes.
  • The log message should clearly indicate the test description and the assertion count.
  • The utility function should not modify the original test function or its behavior.
  • The utility function should work with both test and it blocks.

Expected Behavior:

When trackAssertions is used, the test suite should run as expected, and after each test completes, a message like "My Test: 5 assertions" (where "My Test" is the test description and 5 is the assertion count) should be printed to the console.

Edge Cases to Consider:

  • Tests with no assertions.
  • Tests with a large number of assertions.
  • Tests that throw errors (the assertion count should still be logged).
  • Tests that use asynchronous operations (assertions within async functions or promises).
  • Tests that use beforeEach and afterEach hooks.

Examples

Example 1:

// test.ts
const trackAssertions = (testDescription: string, testFn: () => void | Promise<void>) => {
  let assertionCount = 0;

  const originalTest = testFn();

  return new Promise((resolve, reject) => {
    originalTest.then(() => {
      console.log(`${testDescription}: ${assertionCount} assertions`);
      resolve();
    }).catch((error) => {
      console.log(`${testDescription}: ${assertionCount} assertions`);
      reject(error);
    });
  });
};

describe('My Suite', () => {
  it('My Test', async () => {
    expect(true).toBe(true);
    expect(1).toBe(1);
    expect('hello').toBe('hello');
    expect(2).toBeGreaterThan(1);
    expect([1, 2, 3]).toEqual([1, 2, 3]);
  });
});

Output:

My Test: 5 assertions

Explanation: The trackAssertions function wraps the it block. The test makes 5 assertions, which are counted and logged to the console.

Example 2:

// test.ts
const trackAssertions = (testDescription: string, testFn: () => void | Promise<void>) => {
  let assertionCount = 0;

  const originalTest = testFn();

  return new Promise((resolve, reject) => {
    originalTest.then(() => {
      console.log(`${testDescription}: ${assertionCount} assertions`);
      resolve();
    }).catch((error) => {
      console.log(`${testDescription}: ${assertionCount} assertions`);
      reject(error);
    });
  });
};

describe('My Suite', () => {
  it('Empty Test', async () => {
    // No assertions
  });
});

Output:

Empty Test: 0 assertions

Explanation: The test case contains no assertions. The utility function correctly logs 0 assertions.

Example 3: (Error Handling)

// test.ts
const trackAssertions = (testDescription: string, testFn: () => void | Promise<void>) => {
  let assertionCount = 0;

  const originalTest = testFn();

  return new Promise((resolve, reject) => {
    originalTest.then(() => {
      console.log(`${testDescription}: ${assertionCount} assertions`);
      resolve();
    }).catch((error) => {
      console.log(`${testDescription}: ${assertionCount} assertions`);
      reject(error);
    });
  });
};

describe('My Suite', () => {
  it('Failing Test', async () => {
    expect(true).toBe(false); // This will cause the test to fail
  });
});

Output:

Failing Test: 1 assertions

Explanation: Even though the test fails, the assertion count (1 in this case) is still logged to the console.

Constraints

  • The solution must be written in TypeScript.
  • The utility function must be compatible with Jest's test and it functions.
  • The assertion count must be accurate, even with asynchronous tests.
  • The solution should not introduce any external dependencies beyond Jest and TypeScript.
  • The solution should be relatively performant; excessive overhead is undesirable.

Notes

  • Jest does not provide a built-in mechanism for directly counting assertions. You'll need to use a workaround, such as monkey-patching or using a global counter. Consider using a global counter that is incremented within the expect calls.
  • Be mindful of asynchronous operations and ensure your counter is updated correctly in both synchronous and asynchronous scenarios.
  • Consider how to handle errors gracefully and ensure the assertion count is logged even if a test fails.
  • The provided examples are meant to guide you, but you may need to explore other approaches to achieve the desired functionality. Focus on creating a robust and reliable solution.
Loading editor...
typescript