More Pester Feature and Resources

Doctor Scripto

Summary: Dave Wyatt wraps up his week teaching us about Pester with information about more resources.

   Note   This is a five-part series that includes the following posts:

I hope that this series has convinced you that writing Pester tests for your code can be easy and valuable—even if I had to be fairly brief in my examples of the most essential parts of the module. Today, I want to show you a few of the other features that the module has to offer.

First, coverage analysis! The term “code coverage” refers to how much of your code is actually tested. Pester can help you keep track of this metric by analyzing your code as it’s being tested, and reporting on any PowerShell statements that were not executed during the test. (This doesn’t necessarily guarantee that your tests are covering all the logic of the “hit” commands, but at least you can be certain that if a particular line of code didn’t execute during your tests, you definitely didn’t test that part.)

To show that in action, I’ll run the tests from yesterday’s final script module example, using a –TestName filter to only run one of the Describe blocks:

Image of results

The –CodeCoverage parameter was passed a path to the file that you wanted to analyze, and the –TestName parameter specified which Describe block to run. If you use the –PassThru switch at the same time, the object will include a CodeCoverage property. This property contains detailed information about the analysis, which you can use in your build pipeline if desired.

Image of command output

I snuck in another feature demonstration with the –TestName parameter. Another way to run a particular Describe block or a group of Describe blocks is to use tagging. Each call to Describe can optionally include the –Tags parameter to assign one or more tags to the block. Invoke-Pester can be called with the –Tag or –ExcludeTag parameters to control executing by tag, rather than by name.

Another feature available for your convenience is a set of commands named BeforeEach, AfterEach, BeforeAll, and AfterAll. These are initialization and cleanup blocks. Pester will guarantee to run them at the begin and end of each It block (for the Each versions), or at the beginning and end of the Describe or Context block (for the All versions).

Unlike most PowerShell code, these commands work a bit of magic. You can place them into your code in any order, and they’ll still work, for example:

Image of command output

If your script needs to create temporary files on the hard disk, Pester provides a means for that with a built-in test drive. This is a folder created under your TEMP directory at the beginning of each Describe block. At the end of the Describe, the folder is deleted. You can access it via a variable named $TestDrive, or with a PSDrive named TestDrive:\. Both options refer to the same path. But don’t take my word for it—prove it with tests!

Image of command output

By the way, many of the ideas and code for these cool features came from the community! If you have a feature that you think would make your tests more valuable or easier to write, please head to Pester GitHub site and open an Issue (or, if you’ve already written code, open a Pull Request) to strike up a conversation about it!

Speaking of community contributions, here are some of the neat features we’ve got coming up when version 4.0 of Pester gets released:


Gherkin is a language for defining software requirements entirely in human-readable form, with no executable code whatsoever. It has a minimal amount of syntax rules, similar to YAML in its structure. The advantage is that non-programmers can easily write and maintain the spec for your code, and the spec can then be parsed and used by developers to directly control your automated tests.

If you’re interested in the original Gherkin (part of the Cucumber test framework for Ruby), check out Cucumber: Simple, human collaboration. The credit for bringing Gherkin support to Pester goes to Joel “Jaykul” Bennett, the man behind PoshCode,, and many other cool PowerShell community tools.

Extensible Should operators

Now the operators for the Should command are rather difficult to extend, due to how the arguments passed to Should are parsed. Everything’s limited to this basic syntax:

Should [Not] <Operator> [Value]

There’s no way to add switches or other additional parameters to individual operators.

In Pester v4, we’ll be generating dynamic parameter sets for each operator on the Should command. This will allow the command to be called like this (in the basic case):

$true | Should –Not –Be $false

It looks just like the current syntax, with the exception of the dashes on the Not and Be parameter names. However, this opens up a whole world of options to us for expanding the individual operators. For example, now Should Throw only allows you to match the _message_ of the error that was thrown. But with the new enhancements, we could easily add support for something like this:

scriptBlock | Should –Throw –ExceptionOfType ([MyExceptionType])

Array comparisons

This is another enhancement to parts of the Should command. Now, arrays and the Should command have a weird relationship. Arrays piped to the Should command pass their elements down the pipeline one at a time (because that’s how PowerShell works). In many cases, the operators behave strangely (again, because that’s how PowerShell’s comparison operators work when used on arrays.) Here’s one example of those oddities:

Image of command output

In the code we’re preparing for v 4.0, the Should command and its operators are smarter about how they handle arrays, which will cause the previous example to fail as you would expect:

Image of results

Because this is already going to be a major release (meaning it will include some breaking changes that might require updates to existing Tests.ps1 files), this is a great time to suggest features or fixes to the project. The best way to do that is on the Pester GitHub site. We can’t promise that all suggestions will be included, but for v 4.0, we’ll be less reluctant to make types of changes that we might normally put on hold in a minor release (when _not_ breaking existing test code would be important.)


Thanks for this informative series, Dave!

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

1 comment

Discussion is closed. Login to edit/delete existing comments.

  • Little Nickey 0

    Pictures doesn’t seem to work in this (last of the series) post.

Feedback usabilla icon