4

I'm using Mocha (and Chai) for my unit tests for a NodeJS module and want to debug it in Visual Studio code. I have a TypeScript file in the test subfolder with some tests. VScode generates the .js and .map file in the out dir (via tsc watch mode task). My tsconfig.json file contains these settings:

{
    "compilerOptions": {
        "compileOnSave": true,
        "module": "commonjs",
        "target": "es6",
        "outDir": "out",
        "removeComments": true,
        "noImplicitAny": true,
        "sourceMap": true,
        "inlineSources": true,
        "isolatedModules": false,
        "allowSyntheticDefaultImports": true,
        "experimentalDecorators": true
    },
    "include": [
        "src/**/*", "parser/**/*", "test/**/*"
    ],
    "exclude": [
        "node_modules",
        ".vscode-test"
    ]
}

and the out dir contains 3 subdirs for the 3 includes. All fine so far.

I can run my tests using this command:

mocha --compilers ts:ts-node/register,tsx:ts-node/register

outside of vscode. Then I ran this code with the --debug-brk switch and attached vscode to it. This works, but no breakpoint is hit. The configuration in launch.json for that is:

    {
        "name": "Attach",
        "type": "node",
        "request": "attach",
        "port": 5858,
        "address": "localhost",
        "restart": false,
        "sourceMaps": true,
        "outDir": null,
        "localRoot": "${workspaceRoot}",
        "remoteRoot": null
    }

Ideally, I'd like to have a run config so that I don't need to run mocha manually. With these settings I can at least run the tests:

    {
        "name": "Mocha",
        "type": "node",
        "request": "launch",
        "cwd": "${workspaceRoot}",
        "preLaunchTask": "tsc",
        "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
        "args": [ "--no-timeouts", "--colors", "${workspaceRoot}/out/test/**/*.js" ],
        "stopOnEntry": true,
        "runtimeExecutable": null,
        "env": {
           "NODE_ENV": "testing"
        }
        "sourceMaps": true
    }

but still, no breakpoint is hit.

What is required to make at least one of the 2 scenarios work?

Update: meanwhile I found by accident that breakpoints start working when you add a debugger; command somewhere in the test code and set at least one fresh breakpoint after it stopped on debugger;. After that all following breakpoints in this single file work as expected. Looks almost like a bug to me.

Mike Lischke
  • 48,925
  • 16
  • 119
  • 181
  • I'm on the same boat. Adding a `debugger;` either in the test file or the file with the breakpoint didn't stop execution when the line with the breakpoint executed. Assuming this is a bug, who would own it? – givanse Jan 01 '17 at 22:41
  • Probably not a bug, I built a minimal test case and it worked :/ https://github.com/givanse/vscode-debug-mocha-tests Some other config file or dependency must be messing things up. – givanse Jan 01 '17 at 23:31
  • Well, you wrote a JS test, while I'm using Typescript. That might be part of teh problem. – Mike Lischke Jan 02 '17 at 11:53
  • I've got the same problem with an express app, not hitting the breakpoint unless using 'debugger;'. Using --nolazy to run the app which I had hoped might fix it but still having the issue. – John Stephenson Jan 30 '17 at 21:32

2 Answers2

2

Using "protocol": "inspector", in the launch options helped me to continue for a while, even though this had the annoying side effect that the test process never stopped after everything was executed. I had to kill the task after each run. So I though i'd give it another try to find the problem and I succeeded. The solution is simple: add the outfiles option to your launch options, otherwise vscode will look for maps in the TS source folder. By adding:

        "outFiles": [
            "${workspaceRoot}/out/**/*.js"
        ],

everything started to work nicely. It would so helpfull if vscode would print a warning that it cannot find the source maps because of this missing setting.

Mike Lischke
  • 48,925
  • 16
  • 119
  • 181
0

situtaion

  • using Jasmine unit test (not Mocha)

  • when I click the Debug button on a unit test

    -> it doesnt stop on the breakpoint, just runs to the end.

solution (in short)

(this may not apply to everyone's case)

it could be the port 9229 is taken by other process on your computer

  1. try debugging in terminal, instead of in Vscode, and see what happens (I tried it in powershell)

    eg: node --inspect-brk /usr/local/lib/node_modules/jasmine/bin/jasmine.js ~/exercism/javascript/leap/leap.spec.js

    -> then the error shows up: Starting inspector on 127.0.0.1:9229 failed: permission denied (in my case)

  2. find the process that is using the port & close it (lots online discussion on how to do this)

    • run netstat -ano | findstr 9229
    • or, you can find it in the Task Manager > Resource Monitor > Network > check your ports
  3. run net stop hns && net start hns to restart your Host Network Service

    • I found this especially useful when you cannot find the port is taken by which process -- maybe due to that is a dynamic port
  4. after resetting the port -> click the debug button on unit test -> should stop at breakpoint

---

situation & some comments (minor)

  1. some online posts said:_ add the config in launch.json. doesnt help -- the default launch has no problem

  2. the default config uses port 9229

  3. some online posts said:_ use Chrome config to debug. feels unnecessary & its using the browser not nodejs

  4. output panel in vscode Test Explorer shows nothing to indicate the error

  5. this port issue can due to some software that mess around with dynamic port (eg: sometime could be related to some software that change your system proxy / ip).

    (this once messed up with my other softwares eg: ActivityWatch)

reference (minor)

[]
"port": 9229,
<>
https://github.com/hbenl/vscode-jasmine-test-adapter

[]
1. run node --inspect-brk node_modules/mocha/bin/mocha test.js:
<>
https://youtrack.jetbrains.com/issue/WEB-43747


[]
I managed to start the debugger by running node --inspect-brk with the jasmine.js file called by Jasmine's CLI:

Kurts-MacBook-Pro:bin kurtpeek$ node --inspect-brk /usr/local/lib/node_modules/jasmine/bin/jasmine.js ~/exercism/javascript/leap/leap.spec.js
<>
How to drop into a debugger in a Jasmine test?

[]
Secondly, check if the port is in the excludedportrange by command "netsh int ipv4 show excludedportrange protocol=tcp".
Then check the dynamicport range by command "netsh int ipv4 show dynamicport tcp".
Set the start of dynamicport by command "netsh int ipv4 set dynamicport tcp start=49152 num=16384"

其次,用命令"netsh int ipv4 show excludedportrange protocol=tcp"检查是否在被排除的端口范围内。
然后用命令"netsh int ipv4 show dynamicport tcp"检查动态端口范围。
用命令"netsh int ipv4 set dynamicport tcp start=49152 num=16384"设置起始动态端口。
<>
https://github.com/eggjs/egg/issues/2432

[]
net stop hns && net start hns
<>
An attempt was made to access a socket in a way forbidden by its access permissions. Why?

[]
The port 9229 is the default debug port of the --inspect and --inspect-brk options.
<>
https://code.visualstudio.com/docs/nodejs/nodejs-debugging

Nor.Z
  • 555
  • 1
  • 5
  • 13