Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the steps to follow to debug memory leak in Jest?

My tests in Jest seem to be leaking :

enter image description here enter image description here

What are the recommanded steps to debug that kind of issue?

I'm new to that kind of problem. As you can see, I have tried passing in the options documented in Jest (--forceExit --detectOpenHandles --runInBand --logHeapUsage), but that does not solve my problem.

like image 470
Aymeric Bouzy aybbyk Avatar asked Dec 19 '18 14:12

Aymeric Bouzy aybbyk


1 Answers

I ran into that I needed to debug some tests leaking memory and found that taking a Heapdump of the process running the tests was trickier than expected. If you add the --inspect flag the cli command it will only inspect the jest process.

In order to attach a debugger to your test executer go into node_modules/jest_worker/build/worker.js and add the --inspect flag to the worker. Jest usually strip the --inspect flag.

Use this code:

_initialize() {
  const args = process.execArgv.filter(v => !/^--(debug|inspect)/.test(v));
  args.push('--inspect');
  const child = (_child_process || _load_child_process()).default.fork(
    require.resolve('./child'),
    // $FlowFixMe: Flow does not work well with Object.assign.
    Object.assign(
      {
        cwd: process.cwd(),
        env: Object.assign({}, process.env, {
          JEST_WORKER_ID: this._options.workerId,
        }),
        // Suppress --debug / --inspect flags while preserving others (like --harmony).
        execArgv: args,
        silent: true,
      },
      this._options.forkOptions,
    ),
  );
  ...
}

Finally run your tests like this: node --expose-gc scripts/test.js --env=jsdom --runInBand --logHeapUsage If you have not ejected your react-scripts you may have to do that first, the change can be reverted after you're done debugging. --runInBand is important else you will get too many workers, jest creates one less worker than you have cores in your computer, so it will be hard to inspect / work with them.

Do not add the --inspect flag to the node --expose-gc scripts/test.js --env=jsdom --runInBand --logHeapUsage command since then the jest process will take the default debugger port.

After this step you run your tests and open Google Chrome, navigate to chrome://inspect/ your process will appear in the list of Remote Targets and from there you can do memory profiling and take heap dumps of your test process.

like image 76
JohanShogun Avatar answered Oct 20 '22 13:10

JohanShogun