PowerShell How-To

How To Test PowerShell Modules with Pester

While we covered testing a single script in Pester, here's how to take that knowledge to the next level.

As you progress in writing more advanced PowerShell scripts, you'll soon come to a point to where the code you're writing isn't so simple anymore. Your scripts might be hundreds of lines long and actually confirming what you think they should have done becomes more complicated than simply eyeballing the results. This is a time when you need to start thinking about testing; more specifically looking into unit and integration testing with a project called Pester.

We won't go over what Pester is and how to use it specifically in this article so if you're brand new to Pester, I highly recommend checking out this article on the Hey Scripting Guy blog, which will go over the fundamentals. We will be covering how to use Pester to specifically test your PowerShell modules since there are a few nuances that you need to take into consideration when building unit tests for PowerShell modules.

Like any good test, you'll need to start out with a definition of "working." Regarding a module, this means that you'll need to test general things like if the module is available to be imported, if the module imports correctly and then check the functions inside of the module. Although important, we're not going to cover specific functions due to the variances in what each function in a module might do. Instead, let's go over a basic example of ensuring our module is available to be imported.

Let's first build a Pester test template which we'll be using for the rest of the article.  It will be called MyModule.Tests.ps1, located inside of my module folder and will contain a single describe block.

describe 'MyModule works' {

}

Once we have the describe block, we'll then need to begin adding it blocks inside testing each scenario. Since this is a module, I want to first ensure the module is available to be imported. To do this, I'll create an it block inside of my describe block and call it MyModule_is available to be imported_when called.

describe 'MyModule works' {
it 'MyModule_is available to be imported_when called' {

}
}

I'll then run my test, and assert that Get-Module can find my module using the should function here. Notice that I'm attempting to find MyModule using Get-Module and then piping the result that comes back directly into should. I'm then specifying (in plain terms) that the result should not be equal to $null.

describe 'MyModule works' {
it 'MyModule_is available to be imported_when called' {
Get-Module –ListAvailable | where { $_.Name –eq 'MyModule' } | should not be $null 
}
}

You can see when I run this regularly, I get my module back as available.

Figure 1.

Let's now run this test to ensure my test was written correctly.

[Click on image for larger view.] Figure 2.

You'll notice that my test came back as successful! To ensure my test fails as well, I'll now pull MyModule out of a folder in $env:PSModulePath and test again.

[Click on image for larger view.] Figure 3.

You can now see that it fails as expected since I've moved the MyModule folder out of a folder where the module can be found. That's it! Notice how simple it was to create a Pester test. Granted, I didn't go into the nuances of Pester, but I hope I gave you a good idea of what you can do with Pester and how you can build a more extensive test library for your modules.

About the Author

Adam Bertram is an independent consultant, technical writer, trainer and presenter. Adam specializes in consulting and evangelizing all things IT automation mainly focused around Windows PowerShell. Adam is a Microsoft Windows PowerShell MVP, 2015 powershell.org PowerShell hero and has numerous Microsoft IT pro certifications. He is a writer, trainer and presenter and authors IT pro course content for Pluralsight. He is also a regular contributor to numerous print and online publications and presents at various user groups and conferences. You can find Adam at adamtheautomator.com or on Twitter at @adbertram.

comments powered by Disqus

SharePoint Watch

Sign up for our newsletter.

I agree to this site's Privacy Policy.