I'm working on a legacy JS project which is not using any require/import. When deploying, the files are just concatenated and the result is sent to a server.
In order to write tests with jest, I created a custom environment to load all the JS files in the global context so that I can call the functions in the test file.
For example:
src/index.js
function sum(x, y) {
return x + y;
}
src/index.spec.js
it('should sum two numbers', () => {
expect(sum(1, 2)).toBe(3);
});
jest.config.js
module.exports = {
clearMocks: true,
collectCoverage: true,
collectCoverageFrom: [
"src/**/*.js",
],
coverageDirectory: "coverage",
coverageProvider: "v8",
testEnvironment: "./jest.env.js",
};
jest.env.js
const NodeEnvironment = require('jest-environment-node').TestEnvironment;
const fs = require('fs');
const vm = require("vm");
const path = require("path");
class CustomEnv extends NodeEnvironment {
constructor(config, context) {
super(config, context);
this.loadContext();
}
loadContext() {
const js = fs.readFileSync('./src/index.js', 'utf8');
const context = vm.createContext(this.global);
vm.runInContext(js, context, {
filename: path.resolve('./src/index.js'),
displayErrors: true,
});
Object.assign(this.global, context);
}
}
module.exports = CustomEnv;
When I run npx jest
, the test is executed but the coverage is empty...
Any idea on how to fix the coverage?
I've created a minimal reproducible repo here: https://github.com/GP4cK/jest-coverage-run-in-context/tree/main. You can just clone it, run npm i
and npm t
.
Note: I'm happy to change v8 to babel or load the context differently if it makes it easier.
The issue you're encountering has been reported in the Jest repository. You can find more information on this issue at: https://github.com/facebook/jest/issues/9349 https://github.com/facebook/jest/issues/10645.
Although a fix for the issue was implemented, it was never merged and has become outdated. However, there is an easy fix available that you can contribute yourself as a pull request. You can find the suggested fix at: https://github.com/facebook/jest/pull/10657. The fix has not been completed yet, so it needs someone to finish it.
To implement the suggested fix, you need to remove the one of the culprits at: https://github.com/facebook/jest/blob/main/packages/jest-runtime/src/index.ts#L1268
Specifically, you can comment out the following line:
this._v8CoverageSources.has(res.url) &&
You can quick test the fix locally by commenting out the same line in node_modules:
nodes_modules/jest-runtime/build/index.js:1281
Hope this helps!