Using Pester for Test Driven Development in PowerShell

How do you normally write your PowerShell code? Your answer is probably like mine and most other IT pros. You have a task that you need to accomplish and instead of performing a clicker-size in the GUI whenever that task is required to be performed, you write a PowerShell one-liner, script, or function to automate that task. You test it a little to make sure there aren’t any major issues and you implement it, moving on to the next task.

Have you heard of a PowerShell module named Pester? I’d heard of Pester in the past but never really got past the developer oriented terms that were associated with it. I was missing out big time and didn’t know it and you might be too.

Pester is a PowerShell module designed for performing unit testing on your PowerShell code. Unit testing? What? I can hear most of you now saying “I’m not a developer”. Well, neither am I which is why I added a link to an article on Wikipedia about that subject.

While we’re on the subject of not being a developer, I’ve started using the phrase “writing PowerShell code” to refer to writing PowerShell one-liners, scripts, functions, etc. That’s what you’re writing so get over it IT pros because you can either learn to write some PowerShell code or find a new profession.

While I’m throwing out those nasty developer oriented terms, here’s another one: TDD (Test-driven development). Once again, I’ve linked this foreign term to an article on Wikipedia on the subject for us IT pros. Go read those articles <now>.

Here’s the thought process: Instead of sitting down and writing code to perform some task or resolve a problem, why not write down what your trying to accomplish in the form of tests before jumping in head first and writing code to fix the problem you think you have (you might actually create more problems otherwise). Make sure all of those tests fail and then write PowerShell code to accomplish the necessary tasks until all of the tests pass.

Sounds interesting right? Today is a new day for us IT pros <whether you like it or not>.

First, start out by downloading the Pester PowerShell module from GitHub:

pester1

Unblock the downloaded zip file:

pester2

Extract the files contained in the downloaded zip file to a path in your $env:PSModulePath:

pester3

Rename the “Pester-master” folder to “Pester”:

pester4

Import the Pester module:

pester5

Create a test folder for Pester:

pester6

We’re ready to begin on our first test-driven development task. You’ve been asked to create a PowerShell function to determine the parity  (odd or even) of one or more numbers.

When starting on a new project, task, etc, the first step is to use the New-Fixture function from the Pester module which creates a folder specified via the -Path parameter and two .ps1 files. The .ps1 file is for your PowerShell code and the test.ps1 file is where the tests go:

pester7b

Change to the directory created in the previous step:

pester8

The Invoke-Pester function runs the tests:

pester9

Open both of the files from the NumberParity folder in the PowerShell ISE.

Currently the Get-NumberParity.ps1 file contains a function that doesn’t do anything:

The Get-NumberParity.Tests.ps1 file contains a test that will always fail (which is why all of the test failed when we previous ran the Invoke-Pester function):

Now to define the specifications for what our code is suppose to accomplish in the form of tests. I’ll keep it simple in this blog article and only use the “Should Be” assertion:

Run our test:

pester10

Notice that all of our tests failed. At this step in the process, “failure = success” because we haven’t written any code yet, at least not for the actual Get-NumberParity function and all of the tests are suppose to fail at this point.

As you accomplish tasks when writing your code, test it (test as you go and test often). It’s time to write the PowerShell code for what I think will accomplish the task at hand:

Now to test our newly created Get-NumberParity function by running Invoke-Pester:

pester11

Agh…one of the test is still failing! The problem with using the modulus operator is that negative odd numbers return -1 instead of 1.

pester12

By the way, we’re lucky we decided to write tests for this because there’s no telling how long this code might have been in production before this problem was detected.

We could add a line to our switch statement to account for a value of -1, but that wouldn’t seem to be as clean as it could be and there has to be a better way.

We could divide the number by two and see if it is an integer (has a remainder or not):

That code meets our specifications and passes our tests:

pester13

I guess I’m too much of a perfectionist though because there still seems like there should be a better way to accomplish this task and indeed there is, at least in my opinion. We’ll use one of the bitwise operators:

This code also passes all of our tests with Pester:

pester13

An additional benefit is that you’ll save the tests along with the PowerShell code and in the future when a new feature is needed, you can not only add the new feature using the same test-driven development approach, but you’ll have the original tests to rerun to make sure you don’t break anything in the process of adding new functionality.

The next time your boss shows up and wants to know what you’re working on, tell him you’re refactoring your PowerShell code.

µ

4 Comments

  1. theotherkidd

    Good stuff Mike. Looks like I’m going to have to dip my feet in the Pester waters. Thanks for the info!

    Reply
  2. svangulick

    Great article mike ! During the powershell summit europe 2014, Jim Truher (from the PowerShell team) did a presentation on another module that is used internally at Microsoft called “lite”. Later on he does a demo with the pester module. I thought it might be interesting to share. The recording is available here under:

    Reply
  3. svangulick

    Seems that the link was wrong. It is the 11th video of the play list I was refering to (12 Truher Testing Frameworks in Windows PowerShell) :

    Reply

Leave a Reply

%d bloggers like this: