Using the Script Param to Pass Parameters into Pester Tests

I’m really digging the use of Pester for unit tests and functional tests across my various PowerShell projects. In my recently renamed Vester project, I leverage Pester to comb through a set of configuration values and validate them against a vSphere environment (hence vSphere + Pester = Vester). I had originally set the boolean value for remediation inside of the configuration file, but realized that it would be far more useful if I let the user pass along that decision when Pester is called.

This is especially true for more specific testing, such as isolating just one or two tests, to check for configuration values without necessarily enforcing them. Basically: try before you buy. 🙂

pester-test-pass-params

To grant more control to the testing process, I have begun using the Script parameter available within Invoke-Pester. When a hashtable is passed as a value, the option of passing parameters directly into Pester tests become available. To begin, let’s look at an example:

Invoke-Pester -Script @{Path = '.\Vester\Tests'; Parameters = @{ Remediate = $false ; Config = '.\Vester\Tests\Config.ps1' }}

The first key in the hashtable, Path, is a required entry that tells Pester where to find the tests. While it can be any location on the system, I’ve placed the folder into the root and am thus calling it from there. You can supply any path to where the tests live.

The second key in the hashtable, Parameters, is optional. It contains another hashtable of key/value pairings that will be passed along to the Pester tests. I’m passing two variables along:

  • Remediate: A switch value to trigger remediation for the Pester test as opposed to simply running the test for validation. Essentially – should the Test fix the drifted value, or just report it?
  • Config: A string value that contains the location of configuration values to check against. I see this being handy for complex environments that want to use different values for sections of the data center.

In order to receive the variables being passed by Pester, I’ve also set up params within the Pester tests themselves. As an example, here is my Update-DNS.Tests.ps1 file:

[CmdletBinding()]
Param(
    [Parameter(Mandatory = $true,Position = 0,HelpMessage = 'Remediation toggle')]
    [ValidateNotNullorEmpty()]
    [switch]$Remediate,
    [Parameter(Mandatory = $true,Position = 1,HelpMessage = 'Path to the configuration file')]
    [ValidateNotNullorEmpty()]
    [string]$Config
)

By making both parameters Mandatory and also using ValidateNotNullorEmpty I can ensure that the tests won’t run without supplying inputs. The test then runs against the configuration file supplied and, if it finds a drift in the desired outcome versus the current state, will see if $Remediate has been set to true (switched on). If so, the logic to fix the discrepancy is run.

if ($Remediate) 
                    {
                        Write-Warning -Message $_
                        Write-Warning -Message "Remediating $server"
                        Get-VMHostNetwork -VMHost $server | Set-VMHostNetwork -DnsAddress $esxdns -ErrorAction Stop
                    }

This is just one way that passing parameters to Pester tests can be used, and I hope this example will help anyone else that’s looking to use Pester. I’ve also updated the Invoke-Pester Wiki page with a more detailed description of how the Script parameter works, because I had a hard time with the way it was worded originally and found that people I spoke with didn’t even realize this feature existed. 🙂