Applies to Pester 3.4.0
Like any Windows PowerShell script, a script that contains Pester tests can include parameters. It’s easy enough to run the script and pass parameters and values in the usual way.
But, when you use Invoke-Pester to run the script, you need to pass the parameters in a hash table. This blog explains how to do it.
This post is the third in a series about how to run Pester tests. See also, How to Run Pester Tests and Invoke-Pester: Run Selected Tests.
See the posts in this Pester series:
————————–
To use Invoke-Pester to pass parameters to a script, use a command like this one:
Invoke-Pester -Script @{Path='C:\Tests\MyTests.Tests.ps1';Parameters=@{Name='Pester';Version='3.4.0'}} |
Or, this one:
Invoke-Pester -Script @{Path = 'C:\Tests\MyTests.Tests.ps1'; Arguments = 'Pester', '3.4.0'} |
The Script parameter of Invoke-Pester typically takes a array of paths, either paths to a directory or to scripts that typically contain Pester tests, or both.
But, it can also take a hash table. One hint is that Script parameter type is [System.Object[]], not [System.String[]].
Here are hash table keys:
- Path (required) <string>: The value of the Path key must be a single string, presumably (but not required) the path to directories or files. Wildcards are supported. A hash table with only the Path key is equivalent to submitting a string value to the Script parameter, except that this key is limited to one string.
Invoke-Pester -Script @{Path='C:\Tests\MyTests.Tests.ps1'}
- Parameters <hashtable>: Each key-value pair in the (nested) hash table consists of a parameter name and its value, such as @{ComputerName = ‘localhost’}. Use this key to pass named parameter names and values to a script.
Invoke-Pester -Script @{Path = 'C:\Tests\MyTests.Tests.ps1'; Parameters = @{Name = 'Pester'; Version = '3.4.0'}}
- Arguments <array>: Use this key to pass positional parameter values to a script, such as ‘localhost’, $true or @(‘localhost’, $true).
Invoke-Pester -Script @{Path = 'C:\Tests\MyTests.Tests.ps1'; Arguments = 'Pester', '3.4.0'}
Invoke-Pester splats the parameters and arguments to the scripts as it calls them.
Typically, the Path value in the hash table resolves to a particular script that takes the specified named and/or positional parameters. But, when you pass parameters to a script that has no parameters, the extraneous parameters are ignored, so you can use a directory value effectively.
For example, this command passes the ComputerName to one .Tests.ps1 file, but the command runs all .Tests.ps1 files in the directory and its subdirectories.
Invoke-Pester -Script @{Path = 'C:\Tests\MyTests'; Parameters = @{ComputerName = 'localhost'}} |
Of course, this strategy is error-prone and will not work when more than one of the scripts being run takes different parameters, so it’s probably not advisable.
But, it’s easy enough to pass parameters to a Pester test. Pester really is amazing!
Learning Pester? Check out Real-World Test-Driven Development with Pester. The code and slides are in Github at https://github.com/juneb/PesterTDD.
June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at juneb@sapien.com or follow her on Twitter at @juneb_get_help.
How to Pass Parameters to a Pester Test Script https://t.co/mIZajpYjXq #PowerShell
RT @SAPIENTech: How to Pass Parameters to a Pester Test Script: Applies to Pester 3.4.0
Like any Windows PowerShell script, … https://t.…
Learning #Pester? How to pass parameters to a test script: https://t.co/bWFPMA4WZe Invoke-Pester #PowerShell @SAPIENTech
RT @juneb_get_help: Learning #Pester? How to pass parameters to a test script: https://t.co/bWFPMA4WZe Invoke-Pester #PowerShell @SAPIENTech
@juneb_get_help @SAPIENTech Did you see my PR comment? lol. Talk about nice timing =) I hadn’t realized this until late last night.
@juneb_get_help @SAPIENTech Great article, I was going to ask you if you had written about this yet lol.
RT @juneb_get_help: Learning #Pester? How to pass parameters to a test script: https://t.co/bWFPMA4WZe Invoke-Pester #PowerShell @SAPIENTech
RT @juneb_get_help: Learning #Pester? How to pass parameters to a test script: https://t.co/bWFPMA4WZe Invoke-Pester #PowerShell @SAPIENTech
@juneb_get_help @SAPIENTech Thanks June. I had no idea there was even something called Pester.
Hi,
i am having trouble getting this to work.
[Parameter(Mandatory=$false)]
[string]$setupScript = “../PPE.ps1”
Invoke-Pester -Script @{Path=’C:\test\myprogram.Tests.ps1′;Arguments =’setupScript’, ‘test.ps1’}
for me , setupScript still “../PPE.ps1”
what am i doing wrong?
Thanks,Peter
Hi, Peter,
The Arguments key in the hash table passes the parameter value, “../PPE.ps1” to the ’C:\test\myprogram.Tests.ps1′ script. That script has to have a positional parameter that takes that value.
If that’s the case, you might still have trouble with the relative path. When you don’t enter a path, Pester uses the path in the current directory, not the directory that contains the test file.
If these ideas don’t help, please post on our Windows PowerShell forum. The interface is better for sharing code.
— juneb
June Blender (@juneb_get_help)
Technology Evangelist
SAPIEN Technologies, Inc.
June, for me the solution was to add this to the test.ps1 : . “$here\$sut” -setupScript GetXXX.Helpers.ps1 <– this fixed the parameter.
question : suppose i have multiple PS1 scripts to test, each in a separate directory, , like c:\scripts\test1\a.ps1, c:\scripts\test2\b.ps1 etc etc
Should I run : New-Fixture -Path “Pester Test Suite” -Name “Pester_Test_Suite” in the c:\scripts folder ?
Peter, New-Fixture takes one Path and one Name. When testing multiple scripts, I think it’s best to create your own test files — without New-Fixture. Just be sure to dot-source the script that you’re testing into your test file. That’s what the $here/$sut boilerplate code does generically.
my last questions (For today) . Does Describe”ss” causes xx.ps1 to run right? i want to have a test that deletes a folder at start of test , and then asserts that the folder exists when xx.ps1 is done. Is that possible?
Ignore the first question : – think $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace ‘.Tests.’, ‘.’ causes the script xx to run for xx.tests.ps1 . But still have a question about testing for folder existence.
I answered my second question too (See below) . I assume that I should be using TestDrive , so that each test i’ll start with a empty file system , so that i can test that the files are created in the script being tested, right?
======================================================
Context “files created” {
$directoryInfo = Get-ChildItem C:\junk | Measure-Object
It “returns the correct count” {
($directoryInfo.Count -gt 0) |Should be true
}
}
It’s really hard to answer these questions out of context. It would be much easier if you could post your Pester questions in the ‘Windows PowerShell’ forum: http://www.sapien.com/forums/viewforum.php?f=18
TestDrive creates a new PSDrive for each Describe block in the current user’s temp directory. Child scopes of Describe (Context, It) can create/edit new files and read/write to files created in a parent scope. When you leave a scope, the TestDrive files created in the scope are deleted, but edits to files in parent scope are not rolled back.
To refer to the drive use, ‘TestDrive:’ (note the colon, just like C:) and $TestDrive, which contains the fully qualified path to the current test drive.