Functional / Non-Functional Pester Tests and why I think you really should have a form of both.

Ryan YatesConsultant

Just a dude in his 30's doing things in Tech & trying to break the stigma's around talking about Mental Health

So in this blog post I’m going to cover why there is a need to create Functional & Non-Functional Pester Tests for your PowerShell Modules but before I get into the nitty gritty into the whys behind creating both let me explain what the real differences are between the two because it may not be something that you have previously thought about or considered in your journey up until this point.

Functional

  • Used to test the code’s different use cases
  • Can be either be a form of Unit or Integration Test
  • Where we “Mock” the functionality to confirm it works as expected
  • To Determine the level of code coverage that your tests actually hit
  • Makes Functionality changes simpler and easier going forward as long as you write more Functional tests
  • Should save headaches as code moves between environments as part of a Build/Release Pipeline
  • Provides a Documentation Mechanism to catch either bugs so these can be fixed
  • Provides a Documentation Mechanism to potentially highlight where you may be able to make possible improvements

Non-Functional

  • Can be more referred to as “Traditional Documentation”
  • Aids Newcomers to the code base by being suggestive that you provide some useful help documentation
  • This can also aid newcomers in learning how to understand some of the more advanced functionality
  • We get Validation on the Functions Parameter types – i.e should the parameter be a String for input
  • Confirmations on whether the Parameter a Mandatory Parameter or not ?
  • Gives us a basic form of ParameterSet Validation
  • Gives us a basic form of Parameter Position Validation
  • Does the Parameter Accept Pipeline Input ?
  • Does the Parameter Accept Pipeline Input by Property Name ?
  • Does the Parameter use Advanced Validation at all ?
  • Does the Parameter have at least some help text defined ?
  • Does the Function have at least a basic level of Comment Based Help ? – lets leave the pro’s & con’s for another topic shall we.

So with the additional amount of tests that we may have to write from looking at the above why should we spend the time writing these tests?

This is where the story for Non-Functional tests becomes a little hazy in some ways but it really depends on the situation on how you’ve ended up with this module.

These possibilities can include

You’ve Inherited or downloaded someone else’s code and you have no clue what its doing because it’s

  • Not well documented with little or no help
  • Difficult to read because of the formatting
  • Uses a number of privately scoped functions
  • All the functions are either in a single ps1 or psm1 file
  • Just needs to be refactored to make it easier to manage, maintain & update going forward

Or it may just be that

  • It almost does what you need but you need to extend the functionality
  • You want to dig a little deeper into how it works
  • You are possibly continuing a discontinued open source project
  • Or you are looking at your own older code and want to give it a much needed update considering you’ve become a more experienced scripter than you were when you originally wrote it

If you were to go and create all the Non-Functional Tests that I’ve listed above then this will give you a lot of additional tests (& I mean a lot) that you would then have available to you to provide you some more trust in your code whilst you refactor or just understand how all the bolts fit together.

However I will point out that from this is really meant to provide you with a Singular Set Baseline on what is included in the module and not how the Module actually functions as that’s the role of the Functional Tests to do so.

In my next post I will show you how we can automagically create these Non-Functional Tests for each function included in an existing Script Module, including those functions that are defined as private/internal functions to give us a better chance of being able to manage, maintain & update it going forward.