Nov 4, 2016

Testing Powershell with Pester

Powershell, Pester, TDD

One of the more interesting things that I got to work on lately is write some TTD Powershell. This was pretty cool and I just wanted to share a couple of simple snippets. I used Pester originally started by Scott Muc although it now has over 60 contributors on Github.

These scripts are part of a larger database migration automation piece that I wrote to help us roll changes to various environments. This includes a lot of *.sql and a lot more *.py scripts.

The concept is pretty simple - we store the files in a file structire that looks similar to this:

|8
 └10
  └01 - A story
   | 01 - First script for this story.sql
   | 02 - Second script for this story.py

The script parses out all this and runs the scripts sequentially based on the version the database is at.

So here is what the tests for one of the functions look like, just a simple parser of the version from the file name using regex:

$here   = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut    = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'

. "$here\$sut"

Describe "Get-FileVersionFromName" {
  
  Context "When there is a match" {

    $result = Get-FileVersionFromName "1 - Some script.sql"

    It "Returns the correct version" {
        $result | Should Be "1"
    }
  }
    
  Context "When there isn't a match" {
    $result = Get-FileVersionFromName " - Some script.sql"

      It "Returns null" {
          $result | Should Be $null
      }
    }
}

And the function itself looks like this:

function Get-FileVersionFromName {
    param(
        $name
    )
    
    $matched = $name -match "^(?<Version>\d{0,3}) - .*$"
    
    if($matched -and $matches["Version"]) { 
        return $matches["Version"]
    }
    
    return $null
}

Pretty simple stuff and it makes for a very nice workflow. You can test your Powershell automation and develop some very solid scripts this way. Have fun!

Many thanks to everyone who contributed to the Pester project on Github!