When to write a module and why you should write tests.

Today I’m talking about something a little broader than usual.  I’ve started trying to get comfortable with Pester, which is a framework for writing tests in PowerShell.  The first thing I’ve figured out with Pester is that I’m really not writing well formed scripts.  They’re super hard to test because they aren’t really broken out into distinct elements.  

This prompted me to refactor about all of my core scripts, an unpleasant but important process.  One of the things that has occurred to me is that I, up until now, have been using modules as a bit of a last resort.  I try not to write them if I don’t have to and I often just load functions into an existing catch all tools module.  I just didn’t like putting in the effort to write a module, you need to remember where you stored it and remember to call it in your script*.  

So now looking at the way I bundle my scripts I’ve decided that I like module files.  I can store Variables and functions that are used in my script but never exposed to it.  I can keep my functions bundled together, and I can nest other modules.  It’s pretty handy.  It also keeps my actual scripts really short and makes it easier to add functionality.  I can add a new function to a module or just switch the way I use my existing functions.

My job is largely writing new monitors for large enterprise applications in PowerShell.  I’ve now taken to having every single monitor script call it’s own module.  A monitors gets stored in it’s own folder with at least a monitor script and a module file.  I also add other scripts that support the monitor in there as well.  Like, my tests file so I can validate my monitor after I change it and the configuration data for the Scheduled job that runs it.  It took me a bit to get used to it but I’ve now started writing a lot of modules files and using them in a lot of my scripts.  Anything that can be used for multiple scripts is stuffed into a core module, everything else goes into a script specific module.

I was always hesitant to add external dependencies to my scripts, I worried about breaking something unintentionally.  Well it turns out if you aren’t writing tests for your scripts you are constantly at risk of having them break.  The worst part is if you aren’t testing on a regular basis your only way of knowing a script is broken is when you’re confronted with the results of a failure.  I’ve added external dependancies but I also added tests to provide me absolute certainty that my production scripts are doing what they’re supposed to do.  I feel a lot more confident about my monitors and scripts now than I did before, because when one of them stops doing what it’s supposed to do I know right away.  Production environments can sometimes change on the fly and it’s pretty easy to have a script stop working because someone changed the way an App works.  With good tests you’ll notice something isn’t right well before anyone else does, and that feels really nice.  And with well modularized scripts it’s really easy to adapt to changing circumstances.

Ok so that’s all I have for today, I’d really love feedback on this. How do you feel about modules?  Do you already test your scripts? Is this idea interesting to you or does it sound odd in some way?  

Thanks a lot for taking the time to read this!

*this only applies if it’s not in your PSModulePath and/or you’re in Powershell V2 or below

This entry was posted in Uncategorized. Bookmark the permalink.

4 Responses to When to write a module and why you should write tests.

  1. Dave Wyatt says:

    You’ve pretty much summed up why I prefer to put most of my PowerShell code into script modules these days. It gives me a clear distinction between public API and private implementation details; I can change the private stuff any which way I like, so long as the public contracts are still met. (And having a test suite for Pester helps guarantee that.)

    You might have fun looking through a little side project I started a short while ago, using Pester to help me refactor some really, really bad old code that I wrote: http://davewyatt.wordpress.com/2014/08/09/example-of-dealing-with-crappy-legacy-code/ . It was originally one giant function. I later moved it into a script module so I could publish it to PowerShellGet, and only now did I write some tests for it and start to clean up the code. It’s not finished yet, but I chip away at it now and then when there’s time.

    • rjasonmorgan says:

      Thanks for the response Dave. That’s exactly the sort of feedback I was looking for. It’s a pretty neat project you have, in general it’s hard to find a good Pester tutorial online so looking at tests being built helps a lot.

  2. craibuc says:

    How do you test PowerShell modules (PSM1) with Pester?

    Looking at Pester itself, they’ve split each function into its own PS1 file and associated a testing file with it. The module imports (dot sources) each function. This may be an easier approach.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s