Jest has become the de facto standard for building unit tests. Writing tests in JavaScript / TypeScript is fine, but old hands coming from the .net/java/karma approaches will soon start to miss something... How on God's green earth can I debug this? The answer is using Visual Studio Code !! You can just place breakpoints, choose whether or not to make a single run, enable watch mode, or even only execute the tests of the current opened file.
That's great, so how can I integrate Visual Studio Code debugging capabilities in my Jest based test suite? Just by setting up a launch config file. In this post, you will learn how to do that.
The scenarios that we are going to cover:
How to config Visual Studio Code debugging on a project created from scratch and:
Let's get started!
If you are in a hurry and just need the config files, here you are:
If you want to learn how to configure this step by step, keep on reading :).
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:
First of all, let's enable debugging on our project, in order to do that:
We got a launch.json file under the folder .vscode including a default implementation:
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:
Arguments:
Now we can debug our project:
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"
+ }
]
}
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"
+ },
]
}
First of all, let's enable debugging in our project. In order to do that:
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:
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"
}
]
}
Now we can debug our project:
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"
+ },
]
}
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"
+ }
]
}
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.
Official facebook create-react-app guide for debugging tests (including Chrome configuration).
Microsoft has got a great guide on how to configure jest debugging.
Being able to debug jest unit tests by using our favourite editor can boost our productivity, and setting up all the plumbing is a matter of minutes if you get the right config file. I hope you enjoyed this post.
We are a team of JavaScript experts. If you need coaching or consultancy services, don't hesitate to contact us.
C/ Pintor Martínez Cubells 5 Málaga (Spain)
info@lemoncode.net
+34 693 84 24 54
Copyright 2018 Basefactor. All Rights Reserved.