I am using Mocha to run tests due to it's popularity yet I cannot get the debugger to attach when launching a task to run tests.
What I have started to do is run tests using Grunt with the debug-brk option set to true so that it stops on the first statement and waits for a debugger to connect on port 5858. I can then attach the VS Code debugger and start using breakpoints.
I just discovered that when I attach the debugger in this way I need to make sure that sourceMaps is set to true. By default this option is not even defined with the "Attach" task. This is an important detail. I hope including it here helps others who are working with TypeScript. It would be helpful to add it to the tasks template even with the value set to off like it is for launching tasks.
I am creating this issue in hopes of learning how I can get VS Code to automatically attach to the running Mocha task with it working with source maps so I can debug through TypeScript without the extra step.
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Tests",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/node_modules/.bin/mocha",
"stopOnEntry": false,
"args": ["--reporter", "spec", "--timeout", "5000", "--require", "source-map-support/register", "test/**/*.js"],
"cwd": "${workspaceRoot}",
"runtimeExecutable": null,
"runtimeArgs": [
"--nolazy"
],
"env": {
"NODE_ENV": "dev"
},
"externalConsole": false,
"sourceMaps": true,
"outDir": "${workspaceRoot}/test/"
},
{
"name": "Launch Tests (debug)",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/node_modules/.bin/mocha",
"stopOnEntry": false,
"args": ["--reporter", "spec", "--timeout", "5000", "--debug", "--require", "source-map-support/register", "test/**/*.js"],
"cwd": "${workspaceRoot}",
"runtimeExecutable": null,
"runtimeArgs": [
"--nolazy"
],
"env": {
"NODE_ENV": "dev"
},
"externalConsole": false,
"sourceMaps": true,
"outDir": "${workspaceRoot}/test/"
}
{
"name": "Attach (5858)",
"type": "node",
"request": "attach",
"port": 5858,
"sourceMaps": true
},
]
}
@brennanMKE what version of VS Code are you using and on what platform?
From your description I do not really understand whether there is a real problem with VS Code and mocha tests or whether just the "sourceMap" attribute is missing from the template.
Here are some comments:
sourceMaps to true and specify where the generated JavaScript code lives (via the outDir attribute). But sometimes it is difficult to get the sourceMaps generated correctly (and that makes breakpoint set in TypeScript fail).I'm using mocha tests written in TypeScript for the VS Code node debugger myself (and I'm not using the "--debug", "--require", "source-map-support/register" arguments).
Here is my launch config:
{
"name": "Run Tests",
"type": "node",
"request": "launch",
"cwd": "${workspaceRoot}",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
"args": [
"-u", "tdd",
"--timeout", "999999",
"--colors",
"./tests/out"
],
"runtimeArgs": [
"--nolazy"
],
"sourceMaps": true,
"outDir": "${workspaceRoot}/tests/out"
}
I run my test with this launch config and if I have set a breakpoint in TS source or an exception occurs, I'm landing nicely in the TS source.
I am also having issues to get the debugger to stop at breakpoints when running mocha against ES6 transpiled files with sourceMap.
I created the repository https://github.com/onlyann/vscode-issue-3144 to demonstrate the issue.
If I put a breakpoint in the transpiled file, the debugger stops at the breakpoint displaying the source ES6 file. However, when I put a breakpoint in the source file, it is ignored.
This is happening with version 0.10.8 on Windows.
@onlyann Since your generated JavaScript lives in the builddirectory, you'll have to add this
"outDir": "${workspaceRoot}/build"
to your launch config. Without this, node-debug cannot map from the source to the generated file.
Thanks @weinand . That works.
I read this documentation about outDir but I am not sure I understand how the debugger makes use of this option, or should I say how the debugger maps breakpoints between source and generated file.
I naively assume that when the generated file is loaded, it would use the sourceMap file to locate the source file and that would be enough to discover breakpoints without the use of outDir.
@onlyann source maps map generated code back to source. They do not directly support the reverse mapping (which is required when setting a breakpoint in the source).
In order to find the source map for a source file, it is basically necessary to search all source map files and then look for a reference to that source inside the source map.
Since every project is free to place the generated code and the corresponding source maps wherever it wants, we do not want to perform an exhaustive search on the whole disk. Instead we require that the outDir attribute points to the root folder where to look for generated code and source maps.
The outDir corresponds to the outDir used in the tsconfig.json.
@weinand I think adding the source maps property to the template would be helpful. Adjusting the outDir value did not work for me. I cannot share this code but when I can I will create a sample which I can share on GitHub to demonstrate the issue.
I am working on a Mac with the latest version of VS Code.
I'm writing debugger for ruby and using the same Run Test config as Mock Debug as below
{
"name": "Run Tests",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
"runtimeArgs": [ "--nolazy" ],
"args": [
"-u", "tdd",
"--timeout", "999999",
"--colors",
"./out/tests/"
],
"sourceMaps": true,
"outDir": "${workspaceRoot}/out",
"cwd": "${workspaceRoot}"
}
But breakpoints on my debug adapter never gets hit, whether it's set on TS or JS files. Using the latest VS Code on Mac.
@rebornix running the tests involves two processes: the tests in adapter.test.ts and the debug adapter ruby.ts. If you launch the test with the "Run Tests" launch config you can debug the tests, but not the debug adapter (because that's a different process not started in debug mode).
If you want to debug the debug adapter (while running the test) do the following:
ruby.tsadapter.test.ts:26 add the port number 4711 as a second argument to dc.start(done) so that the tests connect to the ruby debug server (instead of launching the debug adapter).node node_modules/mocha/bin/_mocha -u tdd --timeout 999999 --colors ./out/tests/
Now you should hit the breakpoint.
If you only want to run a single test, just add .only to the test like this:
test.only('should run program to the end'...
@weinand thanks for making it clear! It works as charm.
EDIT:
Sorry!! My fault, I miss configed gulp sourcemaps plugin. Sorry again.
@weinand I'am using vscode 1.1.0 on Windows10, my breakpoint set on a ts file does not get hit. But when I set stopOnEntry to true, vscode can stop at the first statement in the ts file, at this moment, if I set a new breakpoint, the new breakpoint will just work!! I noticed that at the left below corner of debug view, in the BREAKPOINTS window, the breakpoint that can not get hit that I'v set when in editing mode, is displaying √ main.ts 6 src, which src is correct dir of this file, and the breakpoint that gets hit that I've set in debug mode is displaying √ main.ts 6 \.
What would cause this?
My config:
{
"name": "Launch",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/src/main.ts",
"stopOnEntry": false,
"args": [],
"cwd": "${workspaceRoot}",
"preLaunchTask": "default",
"runtimeExecutable": null,
"runtimeArgs": [
"--nolazy"
],
"env": {
"NODE_ENV": "development"
},
"externalConsole": false,
"sourceMaps": true,
"outDir": "${workspaceRoot}/dist"
},
My tsconfig.json
{
"files": [
"src/main.ts"
],
"compilerOptions": {
"noImplicitAny": true,
"target": "es6",
"module": "commonjs",
"sourceMap": true,
"allowJs": true,
"outDir": "./dist"
}
}
I also stumbled on this problem today and after spending several hours trying to figure what I was doing wrong, I found that when setting up the launch configuration, the "program" setting must be set like this:
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
and not like this:
"program": "${workspaceRoot}/node_modules/mocha/bin/mocha",
I have a similar problem. Here's my configuration:
{
"name": "Run Tests",
"cwd": "${workspaceRoot}",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
"args": [
"-u", "tdd",
"--timeout", "999999",
"--colors",
"${workspaceRoot}/.js/tests/**/*.js"
],
"runtimeArgs": [
"--nolazy"
],
"sourceMaps": true,
"outFiles": [
"${workspaceRoot}/.js/*"
],
"type": "node",
"request": "launch"
}
If I put a breakpoint on the js file, then it redirects me to the typescript version. However, without the corresponding .js file opened and a breakpoint set in it it won't work.
The outfiles glob pattern looks wrong. Please try "${workspaceRoot}/.js/**/*.js"
@weinand thanks, that works now!
@weinand @samiraguiar Thank you, this works now!
For breakpoints to work, I had to set protocol to inspector:
{
"type": "node",
"request": "launch",
"name": "Mocha Tests 2",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
"protocol": "inspector",
"args": [
"-u",
"tdd",
"--no-timeouts",
"-r",
"ts-node/register",
"--colors",
"${workspaceRoot}/app/**/*.spec.ts*"
],
"outFiles": [
"${workspaceRoot}/dist"
],
"sourceMaps": true,
"cwd": "${workspaceRoot}",
"runtimeExecutable": null,
"internalConsoleOptions": "openOnSessionStart",
"stopOnEntry": false,
"env": {
"NODE_ENV": "testing"
},
"skipFiles": [
"node_modules/**/*.js",
"<node_internals>/**/*.js"
]
},
@brennanMKE the "outFiles" attribute expects glob patterns. Please use "${workspaceRoot}/dist/**/*.js" when using protocol "legacy".
@PaulStovell Thank you. It fixed the issue to me
I hit this issue today. I had a config almost identical to Paul Stovell above. But it didn't work even with protocol: inspector.
I found this article: https://saravanaj.github.io/2017/02/05/debugging-mocha-tests-written-in-typescript-with-visual-studio-code/ which indicated to run it against the js files instead of through ts-node. So my task becomes:
{
"name": "Debug mocha",
"type": "node",
"request": "launch",
"program": "/Users/rgilling/.nvm/versions/node/v7.2.1/bin/_mocha",
"stopOnEntry": false,
"args": ["--no-timeouts", "dist/**/*.spec.js"],
"cwd": "${workspaceRoot}",
"runtimeExecutable": null,
"sourceMaps": true,
"outFiles": ["${workspaceRoot}/dist/**/*.js"],
"env": {
"NODE_ENV": "test",
"quiet": "false"
}
},
Then when I set break point within the ts code it works fine. Trying to run it through ts-node was not working....
@rgilling I'm not sure that mocha understands a glob pattern argument:
"args": ["--no-timeouts", "dist/**/*.spec.js"],
I just specify the folder with the tests (generated JavaScript):
"args": ["--no-timeouts", "dist"],
@weinand - glob works okay with mocha, I'm trying to add some consistency between the angular 2 code and Node, which is why I'm migrating server code to Typescript. So now my units tests are in the same directories as the regular code, which is a similar layout to angular-cli projects.
@rgilling I have the same issue, but I am only writing JS not TS.. can't hit breakpoints still
@f0ster you do not have the same issue if you are not using TS. Please read https://github.com/Microsoft/vscode/wiki/Submitting-Bugs-and-Suggestions and create a new issue:
Do not add your issue as a comment to an existing issue unless it's for the identical input. Many issues look similar, but have different causes.
Most helpful comment
For breakpoints to work, I had to set
protocoltoinspector: