PowerShell How-To

Using Parameters in your Pester Test Scripts

Save time for accounting for changes in your scripts with this handy tip.

Scenarios are never the same, and neither should be your Pester scripts to test those scenarios. There are a couple of ways to account for these different scenarios. You could create a separate test script for every situation which would be way too cumbersome. Or, you could figure out only what changes amongst those scenarios and use those values as parameters in test scripts. Let's go the easy route here!

For example, perhaps I've got a set of infrastructure tests to ensure a server is online and a service is running. Below is an example:

describe 'SRV1 server' {

it 'SRV1 is online' {

Test-Connection -ComputerName SRV1 -Quiet | should be $true

}



it 'the wuauserv service should be started' {

(Get-Service -Name wuauserv -ComputerName SRV1).Status | should be 'Running'

}

}

This test script is just fine for a single server, but chances are you're going to need these tests for lots of different servers. Rather than creating test scripts like SRV1.ps1, SRV2.ps1, SRV3.ps1, ad nauseam, let's first see what changes across different test scripts and add them as parameters.

Looking at the tests, it appears that we could have two potential candidates for parameters: server name and service name. These values may change, and we need the ability to pass in different values. Adding these values as parameters to a Pester test script is the same process as adding parameters to any general PowerShell script. We add them at the top of the script.

param(

[Parameter(Mandatory)]

[ValidateNotNullOrEmpty()]

[string]$ServerName,



[Parameter(Mandatory)]

[ValidateNotNullOrEmpty()]

[string]$ServiceName

)



describe "$ServerName server" {

it "$ServerName is online" {

Test-Connection -ComputerName $ServerName -Quiet | should be $true

}



it "the $ServiceName service should be started" {

(Get-Service -Name $ServiceName -ComputerName $ServerName).Status | should be 'Running'

}

}

Once we've got the parameters defined at the top and the static value references replaced with parameter variables inside of the script, we now need to pass these parameters to the script using the Invoke-Pester command.

Normally, when invoking a simple test script, we just need the Path parameter.

Invoke-Pester -Path C:\Test.ps1

However, when passing parameters to the test script, we must call Invoke-Pester a little differently. Instead of using the Path parameter, we need to use the Script parameter which requires a hashtable of parameters. Not to be confused with splatting, we're actually creating a hashtable of parameters and passing that hash table to a single parameter on the Invoke-Pester command. The command below performs the same task as above.

Invoke-Pester -Script @{ Path = 'C:\Test.ps1' }

Once you've got the Script hashtable created with the Path key, now you'll need to add a Parameters key to the hashtable which is a hashtable in of itself. It gets a little confusing. In our example, we have a test script with the parameters ServerName and ServiceName. Passing values to those parameters in the test script can be done like below.

Invoke-Pester -Script @{ Path = 'C:\Test.ps1'; Parameters = @{ServerName = 'SRV1'; ServiceName = 'wuauserv'} }

Notice that Invoke-Pester itself is using a single parameter called Script while all of the test script parameters are defined by a Parameters key inside of that hashtable.

Once you've parameterized scripts like this, you'll then be able to pass any number of parameters to test scripts and prevent unnecessary code duplication.