Node.js/Jest

[Jest] How to set up Debug in Visual Studio Code?

brightlightkim 2022. 4. 16. 06:03

Setting up configuration for a create-react-app based project

Let's say you have created your project using the create-react-app Facebook helper. In this case, you don't have direct access to jest, so you have to execute react-scripts to get your tests working.

To follow this guide:

Step 1 Enable debugging in our project

First of all, let's enable debugging on our project, in order to do that:

  • We will click on the debug icon (left hand sidebar).
  • Click on the add configuration option in the dropdown list.
  • Choose nodejs (jest runs under node).
  • A brand new launch.json file will be displayed.

We got a launch.json file under the folder .vscode including a default implementation:

  • In the next step we will replace the content of this file with a new one that will let us integrate the editor with Jest.
  • If you are working on a git repository, check your .gitIgnore file and make sure this .vscode folder is not ignored.

Step 2 Configuring jest test debugging single run

Let's replace the default config file created by VS Code and place the following one:

/.vscode/launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug tests single run",
      "type": "node",
      "request": "launch",
      "env": { "CI": "true" },
      "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts",
      "args": ["test", "--runInBand", "--no-cache"],
      "cwd": "${workspaceRoot}",
      "protocol": "inspector",
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
    }
  ]
}

A little bit of background on this configuration:

  • name: We just provide a friendly name for this configuration.
  • type: Jest runs under node, that's why we set up this value.
  • request: launch a program.
  • env: we set up an environment variable CI: true in order instruct jest to stop the execution once the test battery has been executed.
  • runtimeExecutable: we want to run react-scripts
  • Arguments:
    • test: we are indicating that we want to launch tests.
    • runInBand: run all tests serially in the current process, rather than creating a worker pool of child processes that run tests. Normally Jest parallelizes test runs across processes but it is hard to debug many processes at the same time.
    • no-cache: Disable the cache, Jest caches transformed module files to speed up test execution (in some scenarios this can lead to issues when debugging).
    • watchAll: Watch files for changes and rerun all tests when there is an update on any of the files. Since we are performing a single run we set this flag to false.

Step 3 Debugging our project

Now we can debug our project:

  • Place breakpoints in your code.
  • Click on the debug icon (sidebar).
  • Pick up from the options "Debug Test Single run"
  • Click on the play icon.

Step 4 Configuring jest test debugging watch mode

Sometimes, rather than launching the tests once, you just want to keep the debugging daemon alive and watch for any file change to run them again.

We only need to remove the environment variable entry CI: true from the config:

      "request": "launch",
-      "env": { "CI": "true" },
      "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts",

By default react-scripts will work on watch mode but we can explicitly set this value:

      "args": [
               "test",
               "--runInBand",
               "--no-cache",
+               "--watchAll"
               ],

The resulting launch.json that we get (appended the new configuration in the launch.json file):

/.vscode/launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug tests single run",
      "type": "node",
      "request": "launch",
      "env": { "CI": "true" },
      "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts",
      "args": ["test", "--runInBand", "--no-cache"],
      "cwd": "${workspaceRoot}",
      "protocol": "inspector",
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
+    }
-    },
+    {
+      "name": "Debug tests watch mode",
+      "type": "node",
+      "request": "launch",
+      "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts",
+      "args": ["test", "--runInBand", "--no-cache", "--watchAll"],
+      "cwd": "${workspaceRoot}",
+      "protocol": "inspector",
+      "console": "integratedTerminal",
+      "internalConsoleOptions": "neverOpen"
+    }
  ]
}

Step 5 Only run currently opened file tests

The two prior configurations were great, but what happens if we've got a big project that contains lots of tests? Sometimes we just want to rerun the tests defined on the current, open file that we are editing.

We only need to mention the file that is currently opened, the args section:

"args": [
    "test",
+    "${fileBasenameNoExtension}",
    "--runInBand",
    "--no-cache",
    "--watchAll=true"
],

Full configuration file:

./.vscode/launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Jest Debug Tests Single Run",
      "type": "node",
      "request": "launch",
      "env": { "CI": "true" },
      "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts",
      "args": ["test", "--runInBand", "--no-cache"],
      "cwd": "${workspaceRoot}",
      "protocol": "inspector",
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
    },
    {
      "name": "Jest Debug tests watch mode",
      "type": "node",
      "request": "launch",
      "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts",
      "args": ["test", "--runInBand", "--no-cache", "--watchAll"],
      "cwd": "${workspaceRoot}",
      "protocol": "inspector",
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
    },
+    {
+      "name": "Jest Debug opened file",
+      "type": "node",
+      "request": "launch",
+      "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts",
+      "args": ["test", "${fileBasenameNoExtension}", "--runInBand", "--no-cache", "--watchAll"],
+      "cwd": "${workspaceRoot}",
+      "protocol": "inspector",
+      "console": "integratedTerminal",
+      "internalConsoleOptions": "neverOpen"
+    },
  ]
}

Setting up config for a project created from scratch

Step 1 Enabling debugging in our project

First of all, let's enable debugging in our project. In order to do that:

  • We will click on the debug icon (left hand sidebar).
  • Click on the add configuration option in the dropdown list.
  • Choose nodejs (jest runs under node).
  • A new launch json file will be dispayed.

Step 2 Configuring jest test debugging single run

Let's replace the default config file created by VS Code and place the following content:

/.vscode/launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Jest single run all tests",
      "program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
      "args": ["--verbose", "-i", "--no-cache"],
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
    }
  ]
}

This will work fine if we have all the jest configuration in the package.json file, but what if we have a separate jest config file? We need to set that up by adding a couple of entries to the args section:

  • -c to indicate the path to the jest.json config file.
  • The path to the jest config file (in our case is ./config/test/jest.json if it's located in the root folder it would be ./jest.json).

The final resulting config in this case would look something like this:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Jest single run all tests",
      "program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
      "args": [
+        "-c",
+        "./config/test/jest.json",
        "--verbose",
        "-i",
        "--no-cache"
      ],
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
    }
  ]
}

Step 3 Debugging our project

Now we can debug our project:

  • Place breakpoints in your code.
  • Click on the debug icon (sidebar).
  • Pick up from the options "Debug Test Single run"
  • Click on the play icon.

Step 4 Configuring jest test debugging watch mode

Sometimes, rather than launching the tests once, you just want to keep the debugging daemon alive and watch for any file change to run them again.

We only need to add the parameter watchAll, something like:

      "args": [
               "--runInBand",
               "--no-cache",
+               "--watchAll"
               ],

The resulting launch.json that we get (appended the new configuration in the launch.json file):

/.vscode/launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Jest single run all tests",
      "program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
      "args": [
        "--verbose",
        "-i",
        "--no-cache"
      ],
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
    },
+    {
+      "type": "node",
+      "request": "launch",
+      "name": "Jest watch all tests",
+      "program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
+      "args": [
+        "--verbose",
+        "-i",
+        "--no-cache",
+        "--watchAll"
+      ],
+      "console": "integratedTerminal",
+      "internalConsoleOptions": "neverOpen"
+    },
  ]
}

Step 5 Configuring jest test debugging currently opened file

The two prior configurations were great, but what happens if we've got a big project that contains lots of tests? Sometimes we just want to rerun the tests defined on the current, open file that we are editing.

We only need to mention the file that is currently opened, the args section:

"args": [
    "test",
+    "${fileBasenameNoExtension}",
    "--runInBand",
    "--no-cache",
    "--watchAll=true"
],

Full configuration file:

./.vscode/launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Jest single run all tests",
      "program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
      "args": [
        "--verbose",
        "-i",
        "--no-cache"
      ],
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
    },
    {
      "type": "node",
      "request": "launch",
      "name": "Jest watch all tests",
      "program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
      "args": [
        "--verbose",
        "-i",
        "--no-cache",
        "--watchAll"
      ],
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
-    }
+    },
+    {
+      "type": "node",
+      "request": "launch",
+      "name": "Jest watch current file",
+      "program": "${workspaceFolder}/node_modules/jest/bin/jest",
+      "args": [
+        "${fileBasename}",
+        "--verbose",
+        "-i",
+        "--no-cache",
+        "--watchAll"
+      ],
+      "console": "integratedTerminal",
+      "internalConsoleOptions": "neverOpen"
+    }
  ]
}

Demos source code

You can find all the demo material in the Github Repo jest-vs-code-debugging-example

Each folder contains a starting point and the solution implemented.

Resources

Official facebook create-react-app guide for debugging tests (including Chrome configuration).

Microsoft has got a great guide on how to configure jest debugging.

 

from: basefactor.com/using-visual-studio-code-to-debug-jest-based-unit-tests

 

 

'Node.js > Jest' 카테고리의 다른 글

[AWS-CDK] How to Mock AWS-CDK, DynamoDB  (0) 2022.04.19
[Jest] toBeTruthy()  (0) 2022.04.19
[Jest] Sample Axios Mock Function  (0) 2022.04.16
[Jest] set, clear and reset mock/spy/stub implementation  (0) 2022.04.16
[Jest] Jest Mock Functions  (0) 2022.04.15