Should
This page is incomplete and will be updated as we get closer to release.
Overview
Pester includes a comprehensive set of assertions that you can use to either fail or pass a test. In fact, Pester v6 actually includes two sets of assertions:
- All new
Should-*
assertions introduced in Pester v6, e.g.Should-BeString
,Should-BeTrue
etc. - The
Should
command known from previous version of Pester, invoked using parameter sets likeShould -Be
,Should -BeTrue
etc.
Both types of assertions are supported side-by-side in Pester v6, but we recommend your try out and migrate to the newer assertions.
Should-*
assertions (v6)
Pester v6 comes with a new set of Should-*
assertions that have been built from the ground up.
If you've previously tested the Assert
-module, these will be familiar.
Check out Command Reference in the sidebar to read more about the new assertions, e.g. Should-BeString
.
These new assertions are split these categories based on their usage:
- Value
- Collection
- Generic
- Combinator
Each of these categories treats $Actual
and $Expected
values differently, to provide a consistent behavior when using the |
syntax.
Value vs. Collection assertions
The $Actual
value can be provided by two syntaxes, either by pipeline (|
) or by parameter (-Actual
):
1 | Should-Be -Expected 1
Should-Be -Actual 1 -Expected 1
Using pipeline syntax
When using the pipeline syntax, PowerShell unwraps the input and we lose the type of the collection on the left side. We are provided with a collection that can be either $null, empty or have items. Notably, we cannot distinguish between a single value being provided, and an array of single item:
1 | Should-Be
@(1) | Should-Be
These will both be received by the assertion as @(1)
.
For this reason a value assertion will handle this as 1
, but a collection assertion will handle this input as @(1)
.
Another special case is @()
. A value assertion will handle it as $null
, but a collection assertion will handle it as @()
.
$null
remains $null
in both cases.
# Should-Be is a value assertion:
1 | Should-Be -Expected 1
@(1) | Should-Be -Expected 1
$null | Should-Be -Expected $null
@() | Should-Be -Expected $null #< --- TODO: this is not the case right now, we special case this as empty array, but is that correct? it does not play well with the value and collection assertion, and we special case it just because we can.
# $null | will give $local:input -> $null , and @() | will give $local:input -> @(), is that distinction important when we know that we will only check against values?
# This fails, because -Expected does not allow collections.
@() | Should-Be -Expected @()
```powershell
# Should-BeCollection is a collection assertion:
1 | Should-BeCollection -Expected @(1)
@(1) | Should-BeCollection -Expected @(1)
@() | Should-BeCollection -Expected @()
# This fails, because -Expected requires a collection.
$null | Should-BeCollection -Expected $null
Using the -Actual syntax
The value provides to -Actual
, is always exactly the same as provided.
Should-Be -Actual 1 -Expected 1
# This fails, Actual is collection, while expected is int.
Should-Be -Actual @(1) -Expected 1
Value assertions
Generic value assertions
Generic value assertions, such as Should-Be
, are for asserting on a single value. They behave quite similar to PowerShell operators, e.g. Should-Be
maps to -eq
.
The $Expected
accepts any input that is not a collection.
The type of $Expected
determines the type to be used for the comparison.
$Actual
is automatically converted to that type.
1 | Should-Be -Expected $true
Get-Process -Name Idle | Should-Be -Expected "System.Diagnostics.Process (Idle)"
The assertions in the above examples will both pass:
1
converts tobool
-value as$true
, which is the expected value.Get-Process
retrieves theIdle
process (on Windows). This process object gets converted tostring
which is equal to the expected value.
Type specific value assertions
Type specific assertions are for asserting on a single value of a given type like boolean
.
These assertions take the advantage of being more specialized to provide a type specific functionality, such as Should-BeString -IgnoreWhitespace
.
$Expected
accepts input that has the same type as the assertion type. E.g.Should-BeString -Expected "my string"
.$Actual
accepts input that has the same type as the assertion type. The input is not converted to the destination type unless the assertion specifies it, e.g.Should-BeFalsy
will convert tobool
.
Collection assertions
TODOShould
(v4/v5)
Should
is used to do an assertion that fails or passes the test.
An example of assertion is comparing two strings in case insensitive manner:
"Pester is bad." | Should -Be "Pester is awesome!"
Which throws an exception with this text to fail the test:
Expected strings to be the same, but they were different.
Expected length: 18
Actual length: 14
Strings differ at index 10.
Expected: 'Pester is awesome!'
But was: 'Pester is bad.'
----------^
Other assertion types can be found in Assertion Reference.
Collect all Should failures
Should
can now be configured to continue on failure. This will report the error to Pester, but won't fail the test immediately. Instead, all the Should failures are collected and reported at the end of the test. This allows you to put multiple assertions into one It and still get complete information on failure.
This new Should behavior is opt-in and can be enabled via Should.ErrorAction = 'Continue'
on the configuration object or via $PesterPreference
.
BeforeAll {
function Get-User {
@{
Name = "Jakub"
Age = 31
}
}
}
Describe "describe" {
It "user" {
$user = Get-User
$user | Should -Not -BeNullOrEmpty -ErrorAction Stop
$user.Name | Should -Be "Tomas"
$user.Age | Should -Be 27
}
}
Starting test discovery in 1 files.
Found 1 tests. 51ms
Test discovery finished. 83ms
Describing describe
[-] user 124ms (109ms|15ms)
[0] Expected strings to be the same, but they were different.
String lengths are both 5.
Strings differ at index 0.
Expected: 'Tomas'
But was: 'Jakub'
at $user.Name | Should -Be "Tomas"
[1] Expected 27, but got 31.
at $user.Age | Should -Be 27
Tests completed in 286ms
Tests Passed: 0, Failed: 1, Skipped: 0, Total: 1, NotRun: 0
This allows you to check complex objects easily without writing It for each of the properties that you want to test. You can also use -ErrorAction Stop
to force a failure when a pre-condition is not met. In our case if $user
was null, there would be no point in testing the object further and we would fail the test immediately.