Search code examples
jestjscode-coverageesbuild

How can I ignore a function for coverage?


handler.ts:

Code with lines.

Coverage report:

-----------------|---------|----------|---------|---------|-------------------
File             | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------------|---------|----------|---------|---------|-------------------
All files        |   97.05 |      100 |      75 |   96.96 |
 src             |   96.87 |      100 |   66.66 |   96.77 |
  handler.ts     |   96.87 |      100 |   66.66 |   96.77 | 90

jest.config.js:

module.exports = {
  clearMocks: true,
  transform: {
    '.(js|ts)$': ['esbuild-jest', { sourcemap: true }],
  },
  setupFilesAfterEnv: ['./jest.setup.ts'],
  collectCoverage: true,
};

I bet the transform is the issue, just don't know how to fix it.

Tried:

  • adding /* istanbul ignore next */ on line 88
  • adding /* istanbul ignore next */ after the word export on line 89
  • adding /* istanbul ignore next */ after the word return on line 90

When I do I still get an uncovered line. All the middleware etc makes actually testing that function not worth the effort.


Solution

  • Adding a parsing hint comment is the correct way to ignore a function, but esbuild only includes "legal comments" in the build output (emphasis mine):

    A "legal comment" is considered to be any statement-level comment in JS or rule-level comment in CSS that contains @license or @preserve or that starts with //! or /*!. These comments are preserved in output files by default since that follows the intent of the original authors of the code.

    So given an actual MRE:

    // index.js
    
    export default function foo() {
        console.log("Can't touch this");
    }
    
    // index.test.js
    
    import func from "./index";
    
    it("doesn't test anything", () => {
        expect(true).toBe(true);
    });
    
    // jest.config.js
    
    module.exports = {
        transform: {
            "\\.js$": ["esbuild-jest", { sourcemap: true }],
        },
    };
    
    // package.json
    
    {
      "devDependencies": {
        "esbuild": "^0.17.14",
        "esbuild-jest": "^0.5.0",
        "jest": "^29.5.0"
      },
      "scripts": {
        "test": "jest"
      }
    }
    

    with the output:

    $ npm t -- --coverage
    
    > test
    > jest --coverage
    
     PASS  ./index.test.js
      ✓ doesn't test anything (1 ms)
    
    ----------|---------|----------|---------|---------|-------------------
    File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
    ----------|---------|----------|---------|---------|-------------------
    All files |      50 |      100 |       0 |      50 |
     index.js |      50 |      100 |       0 |      50 | 2
    ----------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        0.16 s, estimated 1 s
    Ran all test suites.
    

    you can get to 100% coverage by adding a parsing hint containing @preserve so that it still appears in the output from esbuild:

    // index.js
    
    /* istanbul ignore next @preserve */
    export default function foo() {
        console.log("Can't touch this");
    }
    

    New output:

    $ npm t -- --coverage
    
    > test
    > jest --coverage
    
     PASS  ./index.test.js
      ✓ doesn't test anything (1 ms)
    
    ----------|---------|----------|---------|---------|-------------------
    File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
    ----------|---------|----------|---------|---------|-------------------
    All files |     100 |      100 |       0 |     100 |
     index.js |     100 |      100 |       0 |     100 |
    ----------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        0.363 s, estimated 1 s
    Ran all test suites.