Pester is a testing framework that allows you to validate the functionality of your PowerShell scripts. In a series of several posts, I will give you an overview of how you can test your PowerShell scripts. In today’s post, I show you how to get started with Pester.

System administrators have traditionally been the ones to use the tools developers provide to them. Although most admins write scripts to automate various tasks, the code is not taken all that seriously. If it works, it works, and it’s time to move on. The problem stems from the mentality that PowerShell scripters have versus that of PowerShell developers. When PowerShell was first brought into the world, its core focus was for system administrators. System administrators loved writing scripts to automate various tasks, but PowerShell was never a development platform, per se.

Fast forward to 2016, where you now have classes, robust debugging support, and a community dedicated to taking PowerShell from being treated just as a scripting language to being acknowledged as a development language. I’m a perfect example of this. I’m a Senior Systems Automation Engineer, and I write PowerShell all day, every day. I check my code into source control, collaborate with others on my code, and am involved in the occasional releases of our automation platform to customers. I’m a PowerShell developer, and at this point, it’s time to get serious and to start investing in testing.

Testing "layers"

Before we get too far into Pester itself, it's important to take a step back and talk about the various "layers" of testing you might see floating around. Pester's Github readme defines the project as "…a framework for running unit tests.". You might not think anything of this snippet, but notice that it doesn’t simply say “tests” and instead gives the test a category: unit. This is important and will soon become evident as you create more tests in Pester.

Software is typically tested in layers: unit, integration, and acceptance (validation). Each layer is unique, which makes each type of test different. Pester is a unit testing framework.

Unit tests

Unit tests aim to test units of code, such as functions, in your project. They are written to confirm whether the logic of the corresponding unit executes as you'd expect it to. Unit tests have no environmental dependencies and can be executed anywhere without fear of actually changing anything.

For example, if you had a script that created a file, a unit test shouldn't test whether the file was actually created. Instead, it would test if your code was designed to create the file in the expected place. A unit test would confirm if your script called Add-Content had a Path argument of C:\CorrectFile.txt, for example, rather than C:\WrongFolder\WrongFilePath.txt; however, it wouldn't actually create the file through a concept called mocking which will be covered in another post.

Integration tests

Integration tests are the next layer of testing. Integration tests actually confirm whether the environment was changed. They reach out to the storage system and confirm if an actual file was created in the right place. Because integration tests interface with other systems, they are always slower than unit tests.

Integration tests are obviously necessary as it’s important to confirm whether your expected change actually happened. For instance, if a unit test confirms that your code is designed to create a file, it doesn’t necessarily mean the script won't fail at doing so. When you bring the environment as a whole into the mix, you could run into things like permission problems, servers being offline, things not existing despite you thinking they would, and many other unforeseen problems.

Acceptance (validation) tests

For the final "testing" layer, we have acceptance testing. Acceptance testing takes things to another level by testing not only if an environmental changed happened but also the expected effect that change has. Acceptance testing ensures that the end result your customer cares about is how you expect it to be.
For example, I'm assuming you didn't just create that file for fun. There had to have been a reason behind it. Perhaps you were creating a configuration file for an IIS server or were placing a file in a certain location for another process to pick up. An acceptance test would examine the final outcome of that process. An acceptance test doesn’t care if the file’s there or not; it cares about whether the service using the file is responding as expected.

Even though Pester is a unit testing framework (and that's what the focus of this article is), it can be adapted to run other testing "layers" as well. We'll go more into this breakdown on unit versus integration testing in a future post.

Installing Pester

That being said, let’s get started with Pester, which we'll first need to download. Pester comes as a PowerShell module that can be obtained through a couple different methods. The easiest way is to use PowerShellGet, using the Find-Module command to retrieve the Pester module from the PowerShell Gallery and then Install-Module to actually install it.

Find-Module –Name Pester | Install-Module
Installing Pester

Installing Pester

Creating a Pester test

Once this is done, you should have all the Pester commands available to you. Next, you'll need to begin developing a set of instructions that Pester understands, and it will essentially confirm whether your code does what you intended. Doing that is a simple matter of creating another PowerShell script with a specific name. Pester is both built in PowerShell and consumes PowerShell scripts as tests.

Your test script needs to always end with .Tests.ps1. This is how Pester recognizes your test script from others in the same path (if no path is provided). Let's say I have a script with code that I'd like to test, called DoSomething.ps1. To do this, I need to create an accompanying .Tests.ps1 file, usually located in the same folder.

  • C:\MyFolder
    • ps1
    • Tests.ps1

You can create the Tests file yourself, or you can use a helpful function, New-Fixture, which comes with the Pester module. This is a command that allows you to specify a path and a name of the test you're building. It then creates the PowerShell script and the test files containing a template, which you can then modify. This is the quickest way to get started.

New-Fixture -Path C:\MyFolder –Name DoSomething

You should now have a test script in C:\MyFolder that looks like this:

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut"
Describe "DoSomething" {
    It "does something useful" {
        $true | Should Be $false

The first few lines dot source your script so that Pester can execute your source code. The describe block below is what could be called a container for your individual tests (It blocks).

Describe and It blocks

The describe block is commonly the same name as the function you are testing or a specific section of code that you feel can be grouped together. Inside the describe block are the actual tests. This is where you'll spend the majority of your time.

Each It block has a name that signifies the item being tested. Useful It block names are descriptive and informative and include a pattern like <ExpectedAction> <GivenCircumstances>. For example, if I wanted to ensure that my code was creating the appropriate Active Directory username, a good test name would be "creates the username with first initial/last name when invoked by something." The given circumstance is sometimes also various parameters passed to the script itself.

Inside of the It block is the actual code that confirms whether the code met your expectations, and it can vary widely depending on the code being tested. Overall, however, the point is to test as many different ways your code can be executed as possible using various Pester assertions.

Subscribe to 4sysops newsletter!

Stay tuned for more articles on Pester wherein we'll dive deep into the various features of this useful testing framework. For a full breakdown on what's possible with the PowerShell testing framework Pester check out The Pester Book by myself and Don Jones.

1 Comment
  1. Eugene 2 years ago

    Hi All.
    Pester is analog Ansible, or not?
    So where is his benefits?

Leave a reply

Your email address will not be published.


© 4sysops 2006 - 2023


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account