I remember attending a meeting on Pester presented by Dave Wyatt back in November 2014 during my first MVP Summit.
A couple of well known PowerShellers were there: Boe Prox, Emin Atac, Adam Driscoll, Mike Robbins, Fabien Dibot, Jan Egil Ring, Steve Murawski, ... It was a great event, great to finally meet all those guys...
Anyway, at the time Pester looked pretty neat but since I only played with it a couple of times and never really invest or commit myself to create tests for each of my scripts or modules.
![]() |
During the Microsoft MVP Summit 2014 week (Bellevue, WA, USA)
Evening event organized by Dave Wyatt on Pester.
|
What is Pester ?
Pester is a Behavior-driven development (BDD) based test runner for PowerShell. Pester provides a framework for running Unit Tests to execute and validate PowerShell commands. Pester follows a file naming convention for naming tests to be discovered by pester at test time and a simple set of functions that expose a Testing DSL for isolating, running, evaluating and reporting the results of PowerShell commands.
Pester tests can execute any command or script that is accessible to a pester test file. This can include functions, Cmdlets, Modules and scripts. Pester can be run in ad hoc style in a console or it can be integrated into the Build scripts of a Continuous Integration system.
Pester also contains a powerful set of Mocking Functions that allow tests to mimic and mock the functionality of any command inside of a piece of PowerShell code being tested. See Mocking with Pester.
Pester tests can execute any command or script that is accessible to a pester test file. This can include functions, Cmdlets, Modules and scripts. Pester can be run in ad hoc style in a console or it can be integrated into the Build scripts of a Continuous Integration system.
Pester also contains a powerful set of Mocking Functions that allow tests to mimic and mock the functionality of any command inside of a piece of PowerShell code being tested. See Mocking with Pester.
My first pester
So I decided that from now on, I'll do my best to deliver tests with any new scripts or modules.
At first, It won't be perfect for sure but I have to start somewhere....
Goal:
My first goal is to verify the Comment Based Help for each of the functions included in the module AdsiPS. I want to make sure that I have a description, parameter description and examples.
I easily see this pester test being expanded to test each of the examples defined in my functions.
Pester Tests:
- Synopsis is not Null or Empty
- Description is not Null or Empty
- Parameters descriptions is not Null or Empty
- Parameters count declared in Help is equal to the Parameter found in the Abstract Syntax Trees (AST)
- Examples count are greater than 0
- Notes contains my information
- Author
- Website
- Twitter Handle
- Github Account
Describe "AdsiPS Module" -Tags "Module" { # Import Module #import-module C:\Test\AdsiPS\AdsiPS.psd1 #$FunctionsList = (get-command -Module ADSIPS).Name $FunctionsList = (get-command -Module ADSIPS | Where-Object -FilterScript { $_.CommandType -eq 'Function' }).Name FOREACH ($Function in $FunctionsList) { # Retrieve the Help of the function $Help = Get-Help -Name $Function -Full $Notes = ($Help.alertSet.alert.text -split '\n') # Parse the function using AST $AST = [System.Management.Automation.Language.Parser]::ParseInput((Get-Content function:$Function), [ref]$null, [ref]$null) Context "$Function - Help"{ It "Synopsis"{ $help.Synopsis | Should not BeNullOrEmpty } It "Description"{ $help.Description | Should not BeNullOrEmpty } It "Notes - Author" { $Notes[0].trim() | Should Be "Francois-Xavier Cat" } It "Notes - Site" { $Notes[1].trim() | Should Be "Lazywinadmin.com" } It "Notes - Twitter" { $Notes[2].trim() | Should Be "@lazywinadm" } It "Notes - Github" { $Notes[3].trim() | Should Be "github.com/lazywinadmin" } # Get the parameters declared in the Comment Based Help $RiskMitigationParameters = 'Whatif', 'Confirm' $HelpParameters = $help.parameters.parameter | Where-Object name -NotIn $RiskMitigationParameters # Get the parameters declared in the AST PARAM() Block $ASTParameters = $ast.ParamBlock.Parameters.Name.variablepath.userpath $FunctionsList = (get-command -Module $ModuleName | Where-Object -FilterScript { $_.CommandType -eq 'Function' }).Name It "Parameter - Compare Count Help/AST" { $HelpParameters.name.count -eq $ASTParameters.count | Should Be $true } # Parameter Description If (-not [String]::IsNullOrEmpty($ASTParameters)) # IF ASTParameters are found { $HelpParameters | ForEach-Object { It "Parameter $($_.Name) - Should contains description"{ $_.description | Should not BeNullOrEmpty } } } # Examples it "Example - Count should be greater than 0"{ $Help.examples.example.code.count | Should BeGreaterthan 0 } # Examples - Remarks (small description that comes with the example) foreach ($Example in $Help.examples.example) { it "Example - Remarks on $($Example.Title)"{ $Example.remarks | Should not BeNullOrEmpty } } } } }
Here is the code in action:
We can see that I already missed a couple of things on the first functions tested >_< ...
Other posts on Pester
- Using Pester to test your Comment Based Help
- Using Pester to test your Manifest File
- Make sure your Comment Based Help is not indented
- Make sure your parameters are separated by an empty line
Resources
Some great resources out there helped me to get started:
No comments:
Post a Comment