The Pester Book Chapter Review ToC

Update: As this project is now complete, I’ve updated the publish date on this Table of Contents post, in order that it comes before (really, it’s after), all 23 of my chapter reviews.

Welcome to The Pester Book Chapter Review, Table of Contents (ToC). Use the below links to read my chapter reviews. If this project isn’t yet completed, you can check back for updates every week, at most. Once done, however, the links will remain so you can read my chapter reviews, as you read the book. If you’re writing PowerShell and haven’t started testing your code, it’s probably time you did.

“…you really should know PowerShell, and if you’re going to have to learn it and write it, then let’s learn to test it, too. Pester is going to be one of those things, that in time, people will assume you know, if you know PowerShell…”
-Tommy Maynard

My Introduction
The Introduction

Part I: Meet Pester

Pester Concepts
Designing for Testing
Describe Blocks
Before and After Blocks
It Blocks
Should
Test Cases
Mocks
The TestDrive Drive

Part II: Using Pester

Design Practices
Adding Tests for a Function
Adding Tests – Again
Working with Pester Output
Infrastructure Validation
Mocking the Unmockable
Troubleshooting Tests

Part III: Using Gherkin with Pester

Using Gherkin with Pester

Part IV: Code Coverage

Why Code Coverage?
Using Pester to Measure Code Coverage
Improving Code Coverage

Part V: Pester Cookbook

Recipe: Testing for Live Conditions
Recipe: Testing for Scheduled Tasks
Recipe: Testing for Installed Software
Recipe: Ensuring all Functions in a Module Have Tests
Recipe: Testing External Applications
Recipe: Testing Syntax
Recipe: Testing Remote Scripts Blocks
Other Resources

The Pester Book Chapter Review (23)

Table of ContentsPart V: Pester Cookbook

Well, this is it. We’re just about done with this project in its entirety. That’s right, we’ve come to the end of The Pester Book chapter reviews. Originally, I was going to do one post per recipe in this section; however, there’s so little to discuss on each that it makes more sense to wrap things up in a single post. And, so here we are.

These recipes, as Adam as chosen to call them, are little, bite-sized mini chapters that discuss a quick topic one might encounter while testing. I especially enjoyed them in that they included simple functions and a simple, corresponding test, or tests. We covered testing for live conditions where we compared a function’s internal WMI call against the actual WMI outside the function, we tested for installed software, determined a way to ensure all the functions in a module have a test, we tested exit codes from executable in scripts, we tested external applications in conjunction with the $LastExitCode automatic variable, we tested syntax errors (think exceptions), and how to handle remote script blocks — that was important to see.

In closing, Adam shared other Pester related resources. There were some I’ve already seen and used, and others I haven’t. I’m not as confident as I’d like to be (and that’s a common theme with me), but after reading this book, I’m armed with enough information to have meaningful conversations about Pester, as well as starting to write more test suites, even as I may need to use Pester included help and the Internet, as I do. It was a good read, and certainly brought me to a new high in my Pester testing knowledge.

Therefore, if you’ve been reading along and learning with me, then we’re both at a better place, as new coding ideas and opportunities start with what do we test, before anything else. I don’t know about you, but I’m looking forward to that next project.

The Pester Book Chapter Review (22)

Table of Contents Improving Code Coverage

This, was a very involved chapter, and it required a good deal of concentration. We first had to understand a good amount of PowerShell that we then had to write tests around. Even so, this turned out to be a great opportunity in that we had not typically seen some of the examples that were included in this chapter. We saw multiple mocks for the same command, mocks that included New-MockObject, a good deal of ParameterFilter parameters on our mocks, and even a Foreach around an Assert-MockCalled command. Awesome.

All that said, the idea behind this chapter wasn’t to present various ideas for testing — although it most certainly did — it was to do a full code walkthrough in regard to code coverage. Once we understood the example function, we met three initial tests someone new at Pester might write. Then the example took off, with a whole new test suite written by Adam. After a multiple page understanding of what had been written, we tested the code coverage. It wasn’t perfect, but it was close. A few changes and we got to a place where the percentage was high enough to feel confident that everything in this function had been tested.

There was a quote I liked, I’ll share in closing. I liked it because we got an image that just like you or me, Adam walked the code in his own mind and extracted those things in which he wanted to test. “These tests were created by following the various code paths of the function. I followed the code from top to bottom and when it “did something,” I created a test for that thing. I followed all code paths.”

Well, next we’ll start Part V, and work to wrap up this chapter-by-chapter book review. I’m excited to finish, but mostly so I can head back and review a touch before I find my next Pester resource. I don’t feel like I know it, know it, so like PowerShell before this, I’ll keep looking for new information to consume in regard to Pester. Back soon.

The Pester Book Chapter Review (21)

Table of ContentsUsing Pester to Measure Code Coverage

Oh man, this was good. This chapter was short, simple, and to the point. In it, we used Pester to measure our code coverage. If you didn’t know this feature was included in Pester, then I suspect you’re grateful now. You should be, as for me at least, I can easily see how this can be helpful. Providing you use it correctly, and get a grasp on what it’s testing and whether it’s testing, then there’s definitely going to be some benefit here.

We discussed a few scenarios during this chapter. These included executing a simple code coverage test — so we could see how this thing works. We saw how Pester will notice untested functions, how Pester will indicate full coverage even if a test doesn’t include an assertion, and how to force a test against a single function, even if there’s more than one in a single .ps1 file. In addition, we saw how we can test a single function by including line numbers for the function, instead of providing the function’s name.

I suspect this was a great intro and build up for the upcoming, and final chapter, in this part of the book. The next chapter looks involved. Time to get started.

The Pester Book Chapter Review (20)

Table of Contents Why Code Coverage?

Welcome to Part IV: Code Coverage. I read this chapter in the most recent version of The Pester Book, which was released on Saturday, April 28, 2018. Be sure to get the newest version if you’re following along. I hope you have been, as according to the ePub file on my iPad, Part IV began with only 51 pages left in the entire book. We’re nearing the end.

Code Coverage is the ability to determine the amount of code that executes as a part of your testing. There are a few metrics, or measurements, that we use along with code coverage. These are statement coverage, branch coverage, path coverage, and condition coverage. Each of these allow us to measure the coverage of code, even as they may sometimes overlap. Be sure to make these, make sense to you.

It was nearing the end of this shorter than normal chapter when it spelled it out like so: “Simply put, code coverage is a way of measuring whether or not you’re executing all of your code through a given set of tests.” In closing here, I do want to bring up test cases. As they were mentioned as a part of this chapter, you may want to head back and review theses if you don’t remember them well. I remember them, but that’s because I’ve put them to use in some of my own testing.

I’m already looking forward to the next chapter, where I’ve spotted some example code. It’ll be helpful to see some examples after this introduction.

The Pester Book Chapter Review (19)

Table of Contents Using Gherkin with Pester

It turns out there’s this whole thing called Gherkin. Before this chapter, all I knew is that I liked saying Gherkin, but that I didn’t really know much else about it (besides the whole cucumber/pickle thing). This single part of The Pester Book had just a single chapter in order to introduce us to Gherkin. I’m not going to try and explain it exactly. What I’ll do instead, is allow the book to partially do it for me. Here’s a quick couple of sentences from the text:

“Gherkin is a Business Readable, Domain Specific Language. It’s meant to decouple the business logic from the actual code being tested. It’s a language that can be used with any development language thus how we’ve been able to use Gherkin with PowerShell and Pester.”

That’s kind of neat, the whole, it can be used with any development language. I guess that’s why it’s in here. I did want to mention that Gherkin appears “…to be more suited for infrastructure testing rather than unit testing.” That’s probably a good thing to know.

Gherkin requires two files. There’s a .feature file and a .steps.ps1 file. One holds code, and one does not. The layout of these two files are specific in that the .feature file contains text description of how the tests will be structured (no code). The actual code — the tests — are located in the steps.ps1 file. These should be kept together inside the same directory with the script, or module, that is being tested. I won’t go into the layouts of each of the files, but it was certainly interesting to see, how each file was dependent on the other in order to execute the code — the tests. You’ll be glad to know that embedded within the .steps.ps1 files was PowerShell, and Pester, used to test the expected vs. the actual results.

I would recommend you work through and understand the example in the chapter. I didn’t really want to at first — I’m doing Pester, not pickle — but in the end, I’m glad I had some exposure to Gherkin, just in case it comes up another time.

Linux Prompt on Windows – Part IX

In the last installment of this series, just published a day ago, I mentioned that I’d like to be able to pass in the fake username and computer name to my prompt function, instead of relying on a hard coded value. Let’s back up, but seriously, only for a second. There’s only so much I’m willing to repeat if you’re starting to read this series at the ninth installment. You can use the links at the very bottom to easily access any of the previous posts.

My prompt function includes my real username and computer name. At times, I like to switch it to a fake username and computer name, so that screen captures won’t include my real information. These hard coded, fake username and computer name values are inside my prompt function as “tommymaynard@cpux1789.” Until now, I wasn’t able to choose the fake username and computer name, and that’s why we’re here today. I’ve added a way to make these values dynamic. I’ve included everything you’d need to copy to your $PROFILE script in order to use this same prompt function. I warn you however, once you start using it, you may not want switch back. And that’s fine, because it just got better.

Here’s an example, before I include the current prompt code. Do notice that the new UserName and ComputerName parameters are completely ignored when the Type parameter value is “Real.” This is because they are not needed in order to use the real username and computer name.

Unfortunately, the Set-Prompt function didn’t feel like a job for ParameterSets. I imagine I could have accomplished “adding” the UserName and ComputerName parameters, when the Type parameter had a value of “Fake,” using dynamic parameters; however, that’s just way too much involvement for now, and would likely bring little return on the invested time. I can be happy with this, at the moment.

Here’s the newest version. Copy it to your $PROFILE script and try it out! You will need a fake, default username and computer name. Toward the bottom of the code, inside the parameter section of the Set-Prompt function, swap out “tommymaynard” for your default, fake username, and “cpux1789,” with your default, fake computer name.

https://gist.github.com/tommymaynard/0dc88b5927ab5f63ee4738d87252fd63

Part VIII | Part VII | Part VI | Part V | Part IV | Part III | Part II | Part I

Linux Prompt on Windows – Part VIII

Update: There’s a part nine, now.

This, is the topic that will never die.

I’m literally about to begin the eighth installment on this topic. There’s no question about it, I love my prompt. In the last installment, we added a more complete PowerShell version number to the prompt, and the entire version number to the WindowTitle. We also added a Type parameter to the prompt function. This allowed me to manually (yuck) edit my function’s Type parameter default value between “Real” and “Fake.” Well, those days are done.

As of now, I’ve removed the default assignment of the Type parameter ([string]$Type = ‘Real’) in the below prompt function. Instead, I added a second function. It’s toward the bottom of the included code, so let’s meet down there.

https://gist.github.com/tommymaynard/4a544e89f71c00abf3611eb18971c71e

Hello again.

The additional function is called Set-Prompt. As the prompt function and this function are in my $PROFILE script, I can expect that they’re both loaded into memory each time a PowerShell host program is opened. In addition to loading the Set-Prompt function into memory, my $PROFILE script also invokes the function. Even though Set-Prompt has a default value for the Type parameter (much like the prompt function had previously), I still pass the “Real” parameter value to the Type parameter.

What this provides is an assurance that my prompt will always be real (include my real username and computer name), when I open a new PowerShell host. If I want to change it to my fake username and computer name for a screen recording, or screen captures, I simply run the below command. The Set-Prompt function doesn’t truly interact with the prompt function. What it does instead, is it updates the $PSDefaultParameterValues variable, so that every time the prompt function is invoked (each new prompt is created), it includes the correct Type parameter value even though we don’t actually see it entered.

Set-Prompt -Type Fake

Since I can’t seem to get away from adding more to my prompt function and this topic, perhaps we’ll do a ninth installment. I would kind of like a way to pass in the fake username and computer name, too. As of now, those values are still hard coded in the prompt function.

Update: I decided to add a graphic to this post. In the below image, although it looks like two different consoles, we’re actually working in the same PowerShell console. In each instance where it was necessary I hid a portion of the computer name. This may actually assist in seeing the real vs. the fake prompt, as I hid a part of my real computer name. The red line helps to indicate the same command in each image.

Part VII | Part VI | Part V | Part IV | Part III | Part II | Part I

The Pester Book Chapter Review (18)

Table of ContentsTroubleshooting Tests

Welcome to the last chapter review of Part II of The Pester Book. We’ve come along way since the beginning. Even the book would agree. According to this chapter, our “training wheels are off…” This is to say that we know some things about Pester now, and really, after all this reading and the overall learning, it’s no surprise. Let’s, “…get down to it.” The purpose behind this chapter isn’t to teach, as much as it’s to determine what we might be able to do as we have problems with Pester.

At first we touched on the option to add a variable inside your script to determine its value during run time. While there’s probably better ways to handle this, we checked our variable’s value from inside the test instead of inside the function. Good to know that the ParameterFilter parameter is just a ScriptBlock, and so we can view the value there. The book agreed there are better ways in which to troubleshoot our tests.

We then moved into breakpoints. This is the more official, and grownup, way to track the values of variables. That said, the example in the book opted to set a breakpoint on a command. That meant that when the command was invoked, the code process stopped in order that we were able to determine the value of a variable right then.

Great stuff, but now, it’s time for Part III. That’s right, Part I and II are officially read and reviewed.

No Prompt Plaster

I took a few hours last week and familiarized myself with Plaster. And no, not the walls and ceiling home improvement project Plaster — Microsoft’s Plaster. The one that requires you search for it alongside the search term PowerShell, otherwise you’ll never get close to what I’m going to briefly discuss.

Plaster allows you to create the folders and files needed for a project, in a repeatable way in order that… well… you don’t have to do it manually. I never quite enjoyed the manual process of most things PowerShell, but especially the process of creating PowerShell script modules: create a folder, rename it, create a .psm1, rename it, create a… Why should I create all the necessary folders and files, if an automated process can do it for me? That’s what this is all about — saving seconds. They add up.

For every video I watched, and post I read, I couldn’t seem to find what I wanted. You see, Plaster by default will prompt you the information needed to create your project. That’s nice and all, and especially because it prompts for the information I’ve determined I need, but how does one run this in an automated fashion already? No one blogged on that (that I read originally), and that’s why we’re here today.

In reading about the Plaster project on GitHub, I read this: “Or you could provide all the required template parameters as dynamic parameters and not be prompted for any of them.” Say what!?

I just knew it had to exist, and there it was — in bold even, in just the right place. For those concerned, I would’ve eventually read the help in full. It’s just what I found first. Honestly though, what I expected to find first was a mention of this in the blog posts and videos I chose to read, and watch. I should note that Mike F. Robbins does mention it here: http://mikefrobbins.com/2018/02/15/using-plaster-to-create-a-powershell-script-module-template. I’d hadn’t quite gotten to that post, as I wondered why I hadn’t found my answer in the first few things I inspected. Do read the link if you have an interest, as Mike includes a full Plaster introduction.

Just in case someone does what I did there for a moment, you don’t have to use Plaster in a manual, you’re-going-to-get-prompted-for-everything manner. Instead, you can do something like the below example, where you provide values to the Plaster parameters you’ve included. Do notice, as Mike mentions, that there’s no tab completion on these parameters. Annoying, but worth it for the automated aspect of Plaster.

Invoke-Plaster -TemplatePath $PSScriptRoot\Tests\TemplateRoot1 -DestinationPath $PSScriptRoot\Tests\Out -ModuleName CoolModule -Version 2.1.1 -License MIT -Options Pester,PSake,Git