My code is throwing an exception when I'm trying to get the test coverage of my project using nyc
.
I'm also using the library node-worker-threads-pool to create a pool of worker threads.
I created a minimal example to emulate the behavior. With this example the behavior is the same, when I execute the test, everything works, but when I try to get the coverage I have an exception.
This is the file where I create the new thread
// thread.js
const os = require('os');
const { DynamicPool } = require('node-worker-threads-pool');
const Pool = new DynamicPool(os.cpus().length, { shareEnv: true });
const someFunction = async (params) =>
await Pool.exec({
task: async function() {
const { params } = this.workerData;
console.log('params', params);
return params;
},
workerData: {
params,
},
});
module.exports = {
someFunction,
};
And this is the test
// thread.test.js
const { someFunction } = require('../thread');
describe('Some Function in another thread', () => {
it('it works', async () => {
const params = 1;
const res = await someFunction(params);
expect(res).to.be.eq(params);
});
});
When I execute NODE_ENV=test mocha --exit 'thread.test.js' --maxWorkers=2
the test passes, but when I tried to get the coverage with nyc NODE_ENV=test nyc --reporter=text --reporter=html --reporter=lcov mocha --exit 'thread.test.js' --maxWorkers=2
the following exception appears:
1) Some Function in another thread
it works:
ReferenceError: cov_vyj5vtdds is not defined
at Object.task (evalmachine.<anonymous>:1:40)
at evalmachine.<anonymous>:1:204
at Script.runInThisContext (vm.js:120:20)
at Object.runInThisContext (vm.js:311:38)
at MessagePort.<anonymous> ([worker eval]:11:29)
at MessagePort.onmessage (internal/worker/io.js:78:8)
at MessagePort.exports.emitMessage (internal/per_context/messageport.js:11:10)
From previous event:
at PoolWorker.work (node_modules/node-worker-threads-pool/src/pool-worker.js:22:12)
at DynamicPool.runTask (node_modules/node-worker-threads-pool/src/pool.js:110:47)
at DynamicPool.exec (node_modules/node-worker-threads-pool/src/dynamic-pool.js:51:17)
at someFunction (src/modules/templates/thread.js:1:1577)
at Context.<anonymous> (test/modules/templates/thread.test.js:6:23)
at processImmediate (internal/timers.js:456:21)
Am I doing something wrong?
So, after doing a little of research I understand that basically nyc
creates variables with random names to count the coverage and insert those inside of all the functions and it uses cloture to access them.
The problem is that it's not possible to use cloture inside of a thread. It's imperative to use the workerData
property to send the arguments to the Worker
constructor. That's why I was having the ReferenceError
exception.
Worker Threads
I didn't really found a solution. But I did find an alternative to nyc
that also uses istambuljs
which is c8
. I no longer have those exceptions with c8
.