pkgs icon indicating copy to clipboard operation
pkgs copied to clipboard

swc/jest - maximum (out of) coverage value channges based on tests run

Open mcshaman opened this issue 5 months ago • 0 comments

When running Jest tests with coverage enabled, reporters such as text text-summary and html show a value of coverage out of a maximum number. This value shouldn't change as it represents the maximum potential coverage for the files scanned by Jest from collectCoverageFrom. However it does change when I add or remove tests or if I only run a sub set of tests.

All tests:

=============================== Coverage summary ===============================
Statements   : 92.38% ( 61559/66639 )
Branches     : 83.83% ( 16807/20049 )
Functions    : 80.31% ( 9038/11254 )
Lines        : 93.07% ( 54584/58649 )
================================================================================

Single test file:

=============================== Coverage summary ===============================
Statements   : 14.19% ( 7343/51748 )
Branches     : 1.43% ( 287/20049 )
Functions    : 2.04% ( 229/11209 )
Lines        : 14.48% ( 6336/43772 )
================================================================================

I did some digging around and found what I think the problem is. The process method conditionally sets the module.type property to es6 or commonjs depending on the value of jestOptions.supportsStaticESM:

                module: {
                    ...swcOptionsForProcess.module,
                    type: jestOptions.supportsStaticESM
                        ? "es6"
                        : ("commonjs" as any),
                },

The processAsync method is almost exactly the same as the process except it doesn't do the jestOptions.supportsStaticESM check and instead just defaults to es6:

                module: {
                    ...swcOptionsForProcess.module,
                    // async transform is always ESM
                    type: "es6" as any,
                },

I was able to confirm the numbers are reliably consistent when:

  • Converting the project test runner to support es6 modules, or
  • Hacking the @swc/jest transformer so that the type is commonjs in processAsync

I don't know if this difference in code was an oversight or has been done on purpose but using the same logic from process in processAsync seems to give a more accurate result.

mcshaman avatar Jul 16 '25 06:07 mcshaman