9

I've recently switched from Vim to VSCode, and I'm trying to set up VSCode debugging for jest tests run through docker.

The debugging works...sort of. If I want to run jest tests and have breakpoints activate, I need to:

  1. Insert the breakpoints
  2. Start running the relevant jest test(s) via the vscode-jest-tests launch.json task below
  3. Quickly execute Docker: Attach To Node before the test suite hits breakpoints

Obviously not ideal - I'd love to ensure VSCode automatically attaches to the debugger upon running vscode-jest-tests. In short: is there an easy way to attach the VSCode debugger when running Jest tests through Docker?

Here are my current launch.json and package.json files. Any help very appreciated:

launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "attach",
      "name": "Docker: Attach to Node",
      "port": 9229,
      "address": "localhost",
      "localRoot": "${workspaceFolder}",
      "remoteRoot": "/www",
      "protocol": "inspector"
    },
    {
      "type": "node",
      "request": "launch",
      "name": "vscode-jest-tests",
      "runtimeExecutable": "npm",
      "runtimeArgs": [ "run", "test:debug" ],
      "address": "127.0.0.1",
      "port": 9229,
      "breakOnLoad": true,
      "restart": true,
      "timeout": 10000,
      "localRoot": "${workspaceFolder}",
      "remoteRoot": "/www",
      "outFiles": [
        "${workspaceFolder}/dist/**/*.js"
      ],
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
    }
  ]
}

package.json

#...
"scripts": {
  "test:debug": "docker exec -it kiva_api node --nolazy --inspect-brk=0.0.0.0:9229 node_modules/.bin/jest --runInBand --config=test/jest-e2e.json"
}
#...

PS: If I run npm run test:debug from the command line & have a chrome debugger window open, Chrome's debugger works just fine

skyboyer
  • 22,209
  • 7
  • 57
  • 64
PlankTon
  • 12,443
  • 16
  • 84
  • 153

3 Answers3

3

Here a shot of my solution, which comes mostly from your same question. Thank you for asking :)

First start jest in watch mode (--watchAll), so the process stays alive. (In the snippet I assume a backend container is running via docker-compose with port 9229 exposed on the host)

docker-compose exec backend \
  node --inspect=0.0.0.0:9229 -r tsconfig-paths/register -r ts-node/register \
  node_modules/.bin/jest --watchAll --runInBand 

Now in VSCode .vscode/launch.json config add a config to attach to the running process. Note: ensure remoteRoot fit your setup.

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
        "type": "node",
        "request": "attach",
        "name": "Docker: Debug tests",
        "address": "127.0.0.1",
        "port": 9229,
        "trace": true,
        "restart": true,
        "timeout": 10000,
        "localRoot": "${workspaceFolder}",
        "remoteRoot": "/app",
        "outFiles": [
            "${workspaceFolder}/dist/**/*.js"
        ],
        "disableOptimisticBPs": true,            
        "internalConsoleOptions": "neverOpen",
        "continueOnAttach": true,
    }]
}

From here on I have been able to develop and debug properly my code.

lcapra
  • 1,420
  • 16
  • 18
  • Every time i try this I get an error `TypeError: Cannot read property 'alias' of undefined at /app/node_modules/jest-validate/build/validateCLIOptions.js:97:58`. It seems `-r tsconfig-paths/register` is causing issues for me – myol Apr 22 '21 at 10:16
  • Not sure, you can try launching the container from a shell (eg `docker-compose exec backend bash`) and test the jest command until it work for your setup – lcapra Apr 22 '21 at 13:08
1

Most of a day later, got it.

VSCode launch.json

{
  "type": "node",
  "name": "docker-jest",
  "request": "attach",
  "address": "0.0.0.0",
  "port": 9229,
  "localRoot": "${workspaceFolder}",
  "remoteRoot": "/app", // Will depend on your setup
  "skipFiles": [
    "<node_internals>/**/*.js",
    "${workspaceFolder}/node_modules/**/*.js"
  ],
  "internalConsoleOptions": "neverOpen",
  "presentation": {
    "reveal": "silent"
  }
},

Ensure your docker container is running with port 9229 open. I used tail -d /dev/null to keep mine running. I wont go into details of a docker setup since there is plenty of online resources on the topic.

Then enter the docker container

$ docker exec -it container_name /bin/bash

And run

$ node --inspect-brk=0.0.0.0:9229 --nolazy -r ./node_modules/ts-node/register ./node_modules/jest/bin/jest.js --config=./jest-config.json --runInBand

The --runInBand flag is key for this to work.

--runInBand causes all tests to be run in the parent process rather than child processes.

You should see something like

root@7a0ba832e7f9:/app# node --inspect-brk=0.0.0.0:9229 --nolazy -r ./node_modules/ts-node/register ./node_modules/jest/bin/jest.js --config=./jest-config.json --runInBand
Debugger listening on ws://0.0.0.0:9229/267bfe8c-dfa8-45e0-a86c-abcadbd97bea
For help, see: https://nodejs.org/en/docs/inspector

Set breakpoints in your Jest .spec.ts files and execute the docker-jest debugger.


If you are continuing to have issues, ensure your app isn't already running in debug mode on the same port. The tests will continue executing with only a brief pause showing the following;

Starting inspector on 0.0.0.0:9229 failed: address already in use

If this happens, just change the debug port used in the node command and launch.json to something else and open the docker port.

myol
  • 8,857
  • 19
  • 82
  • 143
0

This is my launch.json configuration for debugging Jest tests with Docker.

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "name": "Docker: Jest Tests",
      "request": "launch",
      "program": "${workspaceFolder}/node_modules/.bin/jest",
      "args": [
        "--runInBand"
      ],
      "cwd": "${workspaceFolder}",
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen",
      "disableOptimisticBPs": true,
      "windows": {
        "program": "${workspaceFolder}/node_modules/jest/bin/jest",
      },
      "protocol": "inspector"
    }
  ]
}

The idea is start the docker-compose includes a database (Postgres, MongoDB, etc ...) and an api app before run and debug thru VSCode.

Truoc Pham
  • 21
  • 4