VS Code and Pester

I have recently switched to Visual Studio Code for writing PowerShell scripts. (Here is why and how). At the same time I started using Pester to do TDD with PowerShell too. It works very well out of the box, at least at the beginning of a project. As you are writing your Pester tests file to cover the function you have just written you can simply hit F5 to execute all of the tests in that file. Easy.

It’s just that it is backwards. The tests should have already been written, and as you are writing your function that will satisfy the tests you try to press F5 and that function gets executed, not the tests. Even more so, if the function is part a module it gets executed out of context. Nothing works.

Trying to solve my problem I found a very good writeup on Debugging PowerShell in VS Code but it did not answer my question of how to do test driven development with pester and Visual Studio Code.

Eventually to solve my problem I have created workinprogress.ps1 script which I typically keep just outside of the repository and define the following VS Code configuration in my launch.json file.

{
  "version": "0.2.0",
  "configurations": [

  {
    "type": "PowerShell",
    "request": "launch",
    "name": "Test workinprogress",
    "script": "${workspaceFolder}/../workinprogress.ps1",
    "args": [ "${workspaceFolder}", "${workspaceFolder}/tests", "${file}" ]
  }
  ]
}

VS Code will pass the current workspace, the path to the unit tests (${workspaceFolder}/tests in the example), and the open file with the current line number. Based on that information the following will happen when you hit F5

  • if there is a module (.psm1) file in the workspace, the module will be reloaded
  • if the open file name ends with .Tests.ps1 the script will attempt to find the closest pester -Tag and execute only that tag from the current file. Failing that the whole pester file will be executed
  • if it is not a pester file but the matching (by name) test file exists next to the open file, it will be executed.
  • if there is a matching (by name) test file somewhere inside the tests folder (${workspaceFoder}/tests in this example) it will be executed.

A matching test file has the same name as the original file but ends with .Tests.ps1 instead of .ps1. So for a command file Get-MyValue.ps1 the matching tests file is Get-MyValue.Tests.ps1

The workinprogress.ps1 file is available on github here.