Reputation: 1885
Is there a way to use node-inspector to debug unit tests with Jest? It would be nice to step through sometimes to see why tests are failing
I have tried a few ways
node-debug jest --runInBand
from the as well as starting up the inspector first eg
$ node-inspector
$ node --debug-brk .\node_modules\jest-cli --runInBand
and then navigate to http://127.0.0.1:8080/debug?port=5858
I have found that occasionally (1 in 10 or so times), the debugger opens the jest src files and its possible to debug them. Generally though, the scripts in the debugger only contain a 'no domain' folder and another irrelevant folder. Also the test scripts themselves are never loaded in the debugger.
Has anyone tried this before?
Upvotes: 41
Views: 13202
Reputation: 171
Using Node 7.4.0, Jest 18.x, and the jest-environment-node-debug
package (from this comment), it's now possible to use the chrome devtools to debug Jest tests:
$ npm install -D jest-environment-node-debug
$ node --inspect-brk ./node_modules/.bin/jest -i --env jest-environment-node-debug
Upvotes: 5
Reputation: 268255
This is now officially supported with Node >= 6.3.
Quoting Jest documentation:
Place a
debugger;
statement in any of your tests, and then, in your project's directory, run:node --debug-brk --inspect ./node_modules/.bin/jest -i [any other arguments here]
This will output a link that you can open in Chrome. After opening that link, the Chrome Developer Tools will be displayed, and a breakpoint will be set at the first line of the Jest CLI script (this is done simply to give you time to open the developer tools and to prevent Jest from executing before you have time to do so). Click the button that looks like a "play" button in the upper right hand side of the screen to continue execution. When Jest executes the test that contains the
debugger
statement, execution will pause and you can examine the current scope and call stack.Note: the
-i
cli option makes sure Jest runs test in the same process rather than spawning processes for individual tests. Normally Jest parallelizes test runs across processes but it is hard to debug many processes at the same time.More information on the V8 inspector can be found here: https://nodejs.org/api/debugger.html#debugger_v8_inspector_integration_for_node_js
Upvotes: 14
Reputation: 3167
Here's a Gruntfile.js config to automate @Sean's answer with Grunt.
grunt testd
OR
grunt testd --tests=MyTestName
OR
grunt testd --tests=MyTestName,AnotherTestName
Requires "node-inspector" (must be installed globally to get the node-debug bin in your path), "lodash", "jest-cli" and "grunt-shell" node modules.
var _ = require('lodash');
var commaSplitToRegex = function(input) {
return _.map(input.split(','), function(part) {
return '(' + part + ')';
}).join('|');
};
var getTestRegex = function(tests) {
if (tests) {
return '.*' + commaSplitToRegex(tests) + '.*';
}
return '.*';
}
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-shell');
grunt.initConfig({
shell: {
jestd: {
command: function() {
var testsRegex = getTestRegex(grunt.option('tests'));
var cmd = 'node-debug --nodejs --harmony ./node_modules/jest-cli/bin/jest.js --runInBand --config="test_utils/jest.json"';
if (testsRegex) {
cmd += ' "' + testsRegex + '"';
}
return cmd;
}
},
monkeypatchjest: {
command: 'sed -i.bak s\\/harmonize\\(\\)\\;\\/\\\\/\\\\/wtf\\/g ./node_modules/jest-cli/bin/jest.js'
},
unmonkeypatchjest: {
command: 'sed -i.bak s\\/\\\\/\\\\/wtf\\/harmonize\\(\\)\\;\\/g ./node_modules/jest-cli/bin/jest.js'
}
}
});
grunt.registerTask('testd', 'Run tests with debugger.', ['shell:monkeypatchjest', 'shell:jestd']);
};
Upvotes: 4
Reputation: 8605
Looks like the issue is that jest
is using harmonize
, which spawns a child process to ensure that the --harmony
option is used.
var node = child_process.spawn(process.argv[0], ['--harmony'].concat(process.argv.slice(1)), {});
node.stdout.pipe(process.stdout);
node.stderr.pipe(process.stderr);
node.on("close", function(code) {
process.exit(code);
});
I was able to successfully debug jest tests (although tests that use JSX transforms are incredibly slow) by commenting out the code that jest is using to spawn the harmonized process.
if (require.main === module) {
//harmonize(); <--- comment out
_main(function (success) {
process.exit(success ? 0 : 1);
});
}
Then you can run:
$ node-debug --nodejs --harmony ./node_modules/jest-cli/bin/jest.js --runInBand
Jest relies on the --harmony
flag being there, so that's why we need to add it back with --nodejs --harmony
. We also add --runInBand
so that the tests run in sequence, not in parallel.
This opens up the web debugger, and you can debug the tests, although it can be pretty slow to get to the test you want. Please comment if anyone knows a way to make this faster, and I'll update my answer.
You can add this to your package.json
to make it easier to kick off:
...
scripts: {
"test": "jest",
"test-debug": "node-debug --nodejs --harmony ./node_modules/jest-cli/bin/jest.js --runInBand"
}
...
Of course, main concern with this solution is the editing of the jest
source code. Will think about how to make a pull request to make this stick.
Created Github Issue Here: https://github.com/facebook/jest/issues/152
Upvotes: 16