2 min read

Pester Testing in PowerShell

Pester is the ubiquitous testing and mocking framework for PowerShell. It provides a Domain Specific Language (DSL) for writing tests, which helps ensure your scripts work as expected and continue to work after changes.

Parent Topic: PowerShell Scripting and Programming Related: PowerShell Comprehensive Guide

1. Installation

Pester is often bundled with modern versions of PowerShell, but it's good practice to install the latest version from the PowerShell Gallery.

Install-Module -Name Pester -Force -SkipPublisherCheck

2. Core Concepts

Pester tests follow a Behavior-Driven Development (BDD) style, making them easy to read.

  • Describe: The outermost block that groups a set of tests for a specific function or feature.
  • Context: An optional block inside Describe to group related tests (e.g., "when given valid input").
  • It: The block that defines a single test case. It should describe what the code should do.
  • Should: The assertion operator that checks if the output is what you expect.

3. Writing a Basic Test

Let's say you have a simple function in a file named MyFunctions.ps1:

# MyFunctions.ps1
function Add-Numbers {
    param($a, $b)
    return $a + $b
}

Your test file should be named MyFunctions.Tests.ps1.

# MyFunctions.Tests.ps1

# Source the function so the test can see it
. "$PSScriptRoot\MyFunctions.ps1"

Describe "Add-Numbers" {
    It "should add two positive numbers correctly" {
        $result = Add-Numbers -a 2 -b 3
        $result | Should -Be 5
    }

    It "should handle negative numbers" {
        Add-Numbers -a -5 -b 2 | Should -Be -3
    }
}

4. Running Tests

To run the tests, navigate to your project directory and use Invoke-Pester.

Invoke-Pester -Path .\MyFunctions.Tests.ps1

Pester will discover and run the tests, giving you a green/red output indicating success or failure.

5. Common Assertions

Pester's Should command has many operators:

$value | Should -Be "Expected"      # Equality
$value | Should -Not -Be "Other"    # Inequality
$collection | Should -Contain "item" # Collection contains item
$null | Should -BeNullOrEmpty       # Is null or empty string
{ Get-Item "badpath" } | Should -Throw # A script block should throw an error
"C:\file.txt" | Should -Exist       # A file or folder should exist

6. Mocking

Mocking allows you to replace a command with a fake implementation for testing purposes. This is crucial for isolating your function from external dependencies (like web requests or Active Directory cmdlets).

Describe "My Function" {
    It "does something with a user" {
        # Replace Get-ADUser with a fake version for this test
        Mock Get-ADUser { return @{ Name = "Fake User" } }

        # Your function that calls Get-ADUser
        $result = Get-UserReport -UserName "test"

        $result.Name | Should -Be "Fake User"
    }
}

Return to PowerShell Scripting and Programming