- Cloud Automation Software Testing < >
- Checks Type - Runnig Pester in the Background
- Invoke with Output Object
- Get Summary of Pester
- Display only Failed Tests
- PowerShell saves all Errors in $Error Variable
- Prioritize Error
- List All Error Members of latests Error Message
- Stack Trace of Error of latest Error Message - General Tips
Levels, Unit, Integration, System, Acceptence
Per function
Components together
Complete System
Pester is the ubiquitous test and mock framework for PowerShell. Link to Pester
Install-Module -Name Pester -Force -SkipPublisherCheck
Run Test. You can also invoke your test by running Invoke-Pester $Path
.
Code\Pester\Test-Division.ps1
Test it here Code
Example of how to do assertions. You can use the Pipe "|" and Should function to test the output.
Describe 'Notepad' {
It 'Exists in Windows folder' {
'C:\Windows\notepad.exe' | Should -Exist
}
}
Use a generated timestamp to avoid resources to be accidentally deleted by removing the ResourceGroup. Create a dedicated ResourceGroup that you are able to delete after your test case. You can use the Get-Date to create a unique name, but provide a naming convention for dedicated testing groups.
(Get-Date -Format FileDateTime)
Use the capability of BeforeEach
and AfterEach
or (BeforeAll
and AfterAll
for cleanup).
Be sure to have the session connected to your Azure subscriptiong Connecet-AzureRmAccount
Connect-AzureRmAccount
Describe "how to clean up" {
$TestResourceGroupName = "AUTOTEST-$(Get-Date -Format FileDateTime)"
$Location = 'WestEurope'
BeforeEach {
Write-Host "Create Test ResourceGroup $TestResourceGroupName..." -ForeGroundColor Blue
New-AzureRmResourceGroup -Name $TestResourceGroupName -Location $Location | Out-Null
Write-Host "Test started." -ForeGroundColor Blue
}
it "should cleanup" { "A" | Should Be "A" }
AfterEach {
Write-Host "Remove ResourceGroup $TestResourceGroupName..." -ForeGroundColor Blue
Get-AzureRmResourceGroup $TestResourceGroupName -ErrorAction SilentlyContinue | Remove-AzureRmResourceGroup -Force
Write-Host "Test completed." -ForeGroundColor Blue
}
}
Test it here Code
Notice: Use the ForeGroundColor to distinguish the output of the test preparation / cleanup.
If you are using PSScriptAnalyzer you should except PSAvoidUsingWriteHost
A naming convention for ResourceGroups that are created for a test makes it easier to remove them later. To remove all ResoruceGroups you can just search for them based on the naming convention.
$NamingConvention = "AUTOTEST-" # All ResourceGroups for automated testing start with "AUTOTEST-"
Get-AzureRmResourceGroup -Name "$NamingConvention*" | Remove-AzrueRmResourceGroup # -Force
See the Pester Wiki to learn about other assertions that you can use like: Be
, BeExactly
, BeLike
, BeOfType
, BeTrue
, Exist
, Throw
Some examples I frequently use.
If you want to ensure your script is validateing your parameters e.g. when using Parameter and Variable Validations Attributes like [ValidateSet("Blue", "Red")] to get a nice autocomplete feature. Use a Parameter test.
# Returns Color
function My-Function {
param( [ValidateSet("Blue", "Red")] $Color )
$Color
}
Describe "My-Function Parameter" {
It "should throw when value does not match" {
{ My-Function "green" } | should throw
}
Notice the curly braces around the function call My-Function in order to assert the throw.
To test if a particular type is returned for instance when testing AzureResources you can use BeOfType
assertion.
# Checks Type
Describe "New-AzureRmResourceGroup Type" {
$ResourceGroupName = (Get-Date -Format FileDateTime)
It "should be of type PSResourceGroup" {
New-AzureRmResourceGroup -Name $ResourceGroupName -Location 'WestEurope' | Should BeOfType "Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.PSResourceGroup"
}
AfterEach { Remove-AzureRmResourceGroup -Name $ResourceGroupName # -Force
}
}
Test it here Code
Sometimes you are running Pester on a large set of test cases which will for instance just check you PowerShell style see PSScriptAnalyzer.
In order to see a summary of you Pester tests you can use the -PassThru
switch. This allows you to query a Pester object after the tests finish.
So you are able to run the Invoke-Pester
inside a PowerShell job and just have a look at the returned variable.
# Invoke with Output Object
$pester = Invoke-Pester -PassThru
# Get Summary of Pester
$pester
# Display only Failed Tests
$pester.TestResult | ? { $_.Result -eq 'Failed' }
Depending on the amount of errors you can drill into the erros after the tests completion.
PowerShell will save the errors into the Global Variable Error $Global:Error
Best practice should be to clear the error variable in the active PowerShell session before each Pester run.
# PowerShell saves all Errors in $Error Variable
$global:Error.Clear()
$global:ErrorView = "NormalView"
Afterwards you will have a clean Error history in the Error variable that you can look into.
The last Error will be stored in $Error[0]
as the variable is an array of errors.
# Prioritize Error
$Error |
Group-Object |
Sort-Object -Property Count -Descending |
Format-Table -Property Count, Name -AutoSize
# List All Error Members of latests Error Message
$Error[0] | fl * -Force
$Error[0].Exception | fl * -Force
# Stack Trace of Error of latest Error Message
$Error[0].StackTrace
$Error[0].Exception.StackTrace
Thanks Kirk Munro: Become a PowerShell Debugging Ninja
all Pester test scripts must end with .Tests.ps1 in order for Invoke-Pester to run them