2. Describe "Invoke-Reboot" {
Context "When reboots are suppressed" {
Mock New-Item -parameterFilter {$Path -like "*Boxstarter*"}
Mock Restart
$Boxstarter.RebootOk=$false
$Boxstarter.IsRebooting=$false
Invoke-Reboot
it "will not create Restart file" {
Assert-MockCalled New-Item -times 0
}
it "will not restart" {
Assert-MockCalled Restart -times 0
}
it "will not toggle reboot" {
$Boxstarter.IsRebooting | should be $false
}
}
}
A PowerShell Unit Test in the
wild
I’m all about test coverage
Executing all tests in C:devboxstartertestsInvoke-Reboot.tests.ps1
Describing Invoke-Reboot
When reboots are suppressed
[+] will not create Restart file 6ms
[+] will not restart 11ms
[+] will not toggle reboot 4ms
When reboots are not suppressed
[+] will create Restart file 11ms
[+] will restart 5ms
[+] will toggle reboot 2ms
Tests completed in 41ms
Passed: 6 Failed: 0
3. Why Test PowerShell?
Do NOT UnitTest your scripts if
you like surprises!
• Your scripts will likely be
easier to understand
• Catch regressions
• How does your API really
feel?
4. Managed Unit Testing Tools vs.
PowerShell
Managed
• Xunit - https://xunit.codeplex.com/
• Nunit - http://www.nunit.org/
• MSTest
PowerShell
• Pester - https://github.com/pester/Pester
• PSUnit - http://psunit.org/
• PSTest - https://github.com/knutkj/pstest/wiki
If practical, test powershell code in PowerShell:
• Saves the overhead of starting a runspace for each test
• Environment more closely resembles the user’s
8. Isolating file operationsfunction Set-BoxstarterShare {
param(
[string]$shareName="Boxstarter",
[string[]]$accounts=@("Everyone")
)
foreach($account in $accounts){
$acctOption += "/GRANT:'$account,READ' "
}
IEX "net share $shareName='$($Boxstarter.BaseDir)' $acctOption"
if($LastExitCode -ne 0) {
Throw "Share was not succesfull."
}
}
Describe "Set-BoxstarterShare" {
$testRoot=(Get-PSDrive TestDrive).Root
Context "When setting share with no parameters" {
MkDir "$testRootboxstarter" | Out-Null
$Boxstarter.BaseDir="$testRootBoxstarter"
Set-BoxstarterShare
It "Should create Boxstarter Share"{
Test-Path "$env:ComputernameBoxstarter" | should be $true
}
It "Should give read access to everyone"{
(net share Boxstarter) | ? { $_.StartsWith("Permission")} | % {
$_.ToLower().EndsWith("everyone, read") | Should be $true
}
}
net share Boxstarter /delete
}
}
Using the Pester TestDrive:
9. Testing Exceptionsfunction Set-BoxstarterShare {
param(
[string]$shareName="Boxstarter",
[string[]]$accounts=@("Everyone")
)
foreach($account in $accounts){
$acctOption += "/GRANT:'$account,READ' "
}
IEX "net share $shareName='$($Boxstarter.BaseDir)' $acctOption"
if($LastExitCode -ne 0) {
Throw "Share was not succesfull."
}
}
Context "When share already exists" {
MkDir "$testRootboxstarter" | Out-Null
$Boxstarter.BaseDir="$testRootBoxstarter"
Net share Boxstarter="$($Boxstarter.BaseDir)"
try {Set-BoxstarterShare} catch{$ex=$_}
It "Should throw exception"{
$ex | should not be $null
}
net share Boxstarter /delete
}
10. Debugging Tests
Doug Finke’s IsePester
https://github.com/dfinke/IsePester
Chocolatey (downloads pester,
isepester and imports them in your
ISE profile):
cinst IsePester
Ctrl+F5
Debugs tests in the active editor