In a current Node.js / Docker customer project I had to debug some mocha tests because Docker containers use UTC and you know: that timezone stuff...
In the end, I was debugging my mocha tests using WebStorm and node-inspector inside the containers and got stuff running.
As I have been playing around with Visual Studio Code recently and debugging Node.js in Docker containers as well as debugging mocha tests (both using VS Code), this thought came up: "how would I be able to debug mocha tests using Visual Studio Code in Docker containers?"
In the end, it worked out to be pretty staight forwarded.
Make sure to have ES6 enabled in jsconfig.json
for the sample code:
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs"
}
}
First, I have a little express application inside ./index.js
:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.status(200).send('hello world');
})
app.listen(3000);
This application isn't really required for our tests but my aforementioned scenario was like it. Furthermore we need a process that prevents our container from exiting after he has been started, so we'll stick with that little app.
Next, we have a Dockerfile
:
FROM node:4.2.3
EXPOSE 3000
EXPOSE 5858
COPY . /app
WORKDIR /app
RUN cd /app; npm install
CMD ["node","index.js"]
As this post is about debugging mocha tests, here's our little test (./test/test.js
) we want to debug inside the container:
const assert = require('assert');
describe('Truth', () => {
it('should be told', (done) => {
assert.equal(true, true)
done()
})
})
The idea of how I want to debug this test inside a Docker container is as follows:
--debug-brk
at port 5858
to wait for Visual Studio Code to attach to the debuggerThere is another viable method:
index.js
--debug-brk
and port 5858
in the Dockerfile
CMD
As I don't want to have a container dedicated for debugging of mocha tests, I prefer the first version.
Starting the container consists of building the image and running the container. This can be easily automated using nodemon
, grunt-watch
or something similar. You could even use a Docker Volume and not restart the container at all.
Whatever automation you choose, here are the commands to build and run the container:
$ docker build -t vscodemocha .
$ docker run -d --name vscodemocha -p 3000:3000 -p 5858:5858 vscodemocha
With our container being up and running, we can configure Visual Studio Code to run mocha inside the container.
The Visual Studio Code attach
Configuration allows to provide a preLaunchTask
which is a task that can be defined inside the tasks configuration in tasks.json
.
So we'll simply create a runmochaindocker
task based on the bash
command in tasks.json
(inside the .vscode
folder):
{
"version": "0.1.0",
"isShellCommand": true,
"command": "bash",
"args": [
"-c"
],
"tasks": [
{
"taskName": "runmochaindocker",
"showOutput": "always",
"suppressTaskName": true,
"args": [
"docker exec -i vscodemocha bash -c \"./node_modules/mocha/bin/mocha --debug-brk=5858 -t 10000 test/test.js\""
]
}
]
}
Having that done, we're now referencing that task in the attach
configuration in launch.json
:
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Mocha in Docker",
"type": "node",
"request": "attach",
"port": 5858,
"preLaunchTask": "runmochaindocker",
"address": "localhost",
"restart": false,
"sourceMaps": false,
"outDir": null,
"localRoot": "${workspaceRoot}/",
"remoteRoot": "/app/"
}
]
}
As already said, runmochaindocker
now is defined as a preLaunchTask
. And as already described in my recent post on debugging a Node.js app in a Docker container, I set localRoot
and remoteRoot
accordingly.
Guess what? We're done!
Just hit F5 now, and you'll get this:
Then, hit F5 again:
(To be honest, I'm not sure why the debugger breaks here - but we can ignore that).
Hit F5 one last time, and we're there: debugging our mocha test in a Docker container:
Happy debugging!