Debug Unit Tests in VSCode using Jest, Typescript, Javascript and of cause Vue

Hi folks!

Yesterday I spent a lot of time to enable debugging for my unit tests in Visual Studio Code. Unfortunatelly I did not find anything out of the box in the web, that made it work for me. Therefore I want to share it with you now, that you save this time.

I am using jest as testing framework and my Vue project contains both, typescript and javascript files. I set the Vue project up with the Vue.cli 3.0, so there is a lot already configured right from the start, like Typescript, Jest and Babel, which is quite convenient! Therefore I will not mention this part of the setup, but only the missing pieces, mainly how to integrate this into the debugging feature of Visual Studio Code?

But before that there is also one small additional change that I had to apply to jest configuation file (jest.config.js). As I use both Typescript and Javascript I had to add the transformation for Javascript to the file. Because Vue.cli 3.0 only added this for Typescript. So the transform property finally looks like this:

transform: {
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
'^.+\\.tsx?$': 'ts-jest',
"^.+\\.js$": "<rootDir>/node_modules/babel-jest"
  },

After reading lots of documents I finally created this configuration for the VSCode Debugger that luckily works now. I hope it works for you, too. You need to enter it in the “launch.json” file in VSCode.
For this, open the Debug perspective, click on the options sign on the upper left with the tooltip "Configure or fix ‘launch.json’ " and choose for example “node.js” from the drop down menu.
Then the launch.json file is opened in the editor. Here just replace the example configuration with the following:

"version": "0.2.0",
  "configurations": [
    {
      "name": "vscode-jest-tests",
      "type": "node",
      "request": "launch",
      "runtimeArgs": [
        "--inspect-brk",
        "./node_modules/@vue/cli-service/bin/vue-cli-service.js",
        "test:unit",
        "--runInBand"
      ],
      "cwd": "${workspaceFolder}",
      "protocol": "inspector",
      "disableOptimisticBPs": true,
      "console": "integratedTerminal",    
      "internalConsoleOptions": "neverOpen",
      "outFiles": [ "${workspaceFolder}/src/**/*.js"],
      "port": 9229
    },
  ]

Now a new configuration “vscode-jest-tests” will show up in the debug view next to the “settings” icon in VSCode. You can start to run and debug your unit tests with the “run”-sign (arrow) next to your new configuration.

So this works for me but I am not an expert. So there might still be issues in your environment with that script that I can’t help with. However for a fresh project created with Vue.cli 3.0 this works.

3 Likes

Thank you! You save my day :sweat_smile:

1 Like

I am happy to hear that it supported you, Pedrazi! :smiley:

This helps a lot, thank you! I was able to debug .ts files with this which is a huge step forward. I’m curious, are you using outFiles to output source maps to the /src/ folder to allow debugging of .vue files with this config? With my cli 3 project, breakpoints in my .vue files are always unverified. Not a big deal since most of my JS will be in a vuex store, but just curious if you’re using some type of build that provides source maps for the vue files

Oh yes, you are right! It does not stop in .vue files. I did not notice as I do it just like you: I also execute most logic in the store.
And to be honest, I have no bloody idea, if there is any sourcemapping enabled in this build - I guess not.
As I wrote I just used a plain out of the box installation with Vue.cli 3.0.
Please let me know in case you found some solution!
Otherwise I have to admit that my solution described above obviously still seems to lack the debugging of .vue files in unit testing. :roll_eyes:

Ok I’ll keep digging. Sadly I discovered it only seems to break in the spec.ts files, and not any other .ts, so the store can’t be debugged either :frowning:. Still, this is much better than any other config I can find. I think the source maps are the missing piece, if I find any more info on this I’ll update this thread.

You actually don’t need to configure much, all you need is to make sure the vue cli service is being called during the debugging and that the proper port is attached. You don’t even need to specify the output directory or add a transform (if your project was made with the VUE CLI originally).

The only complications people may run into is possible errors in babel with polyfills. Like if you get an import error with es6 then you can add the library like this in the babel.config.js file

module.exports = {
  presets: [
    [
      "@vue/app",
      {
        polyfills: ["es6.array"]
      }
    ]
  ]
};

So with your configuration above and output directory removed, I was able to debug even .vue files without issues. Combined with the jest extension it even works debugging a single test at a time if needed.

{
"version": "0.2.0",
  "configurations": [
    {
      "name": "vscode-jest-tests",
      "type": "node",
      "request": "launch",
      "runtimeArgs": [
        "--inspect-brk",
        "./node_modules/@vue/cli-service/bin/vue-cli-service.js",
        "test:unit",
        "--runInBand"
      ],
      "cwd": "${workspaceFolder}",
      "protocol": "inspector",
      "disableOptimisticBPs": true,
      "console": "integratedTerminal",    
      "internalConsoleOptions": "neverOpen",
      "port": 9229
    },
  ]
}

I have used the auto-attach-feature of VSCode to great success - with 0 configuration. Just enable auto attach (there should be a button for that in the status bar - if not use the command palette to toggle it’s state) and then start your tests via npm from the integrated terminal. A few releases back VSCode made lots of changes in that area. In the release notes they even acknowledged that configuring VSCode can be a pain and that auto attach is one part to make life easier.

Here are the release notes from back then:

Observations and pain points

So I usually execute the tests from the Terminal and just ensure that --runInBand and --inspect-brk is used.

Obviously, a well configures VSCode is nicer. :slight_smile:

So I found what the issue was in my environment. The only change I had to make using the launch.json in the OP, and the base vue-cli config for babel/typescript/jest was to add '!**/dist/**', to the testMatch array inside the jest.config.js file. It seems that including that folder was confusing the debugger because the built javascript and original typescript were both trying to be debugged at the same time.

After I add that, my debugger stops inside .vue and other .ts files besides just the spec.ts files like a charm! It continues to work even if I completely exclude the outFiles in the launch.json and do not build anything with source maps.

Another complication with this config, it seems using that dist folder exclusion I noted above is now breaking the code coverage reporting! Tests are passing but the coverage outputs the following:

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |  Unknown |  Unknown |  Unknown |  Unknown |                   |
----------|----------|----------|----------|----------|-------------------|

I’m really not sure why that would be the case, but it seems to be the same behavior if I replace dist with node_modules so I’m thinking the test match needs to access certain packages to get the coverage output.

Really wish this would be as simple as above posters say it should be, but using defaults and auto attach is not behaving properly at all. I’ll keep digging when I have time…

Edit: This appears to be related to this issue: https://github.com/facebook/jest/issues/7165

Edit 2: Very strange, if I change the exclusion patter from /dist/ to anything even just jibberish, the same behavior exists. It seems that whatever is breaking the coverage is also fixing the debugging! Maybe this info helps someone know what’s going on here?