Friday, May 3, 2013

PowerShell, Tests and CI/D

Maybe you have an ASP.NET web site, and maybe you have a collection of PowerShell modules used for various automation tasks, like moving files between environments, kicking off batch processes, moving assets to the your CDN or similar things. If so these bits of PowerShell contain important bits of logic; if they don't work your site doesn't work properly.

Naturally you want to apply the same discipline to the PowerShell code as to any other production code, which includes TDD and Continuous Integration/Delivery/Deployment (CI/D). Furthermore I'll assume that you already have tests around your C# code, and that your CI/D setup runs these tests and reports the result.

In this situation you can TDD by writing test functions in the PowerShell modules themselves and call them from the command line. This, of course, becomes tiresome quickly as the number of tests rise, so you'll soon find yourself  writing ad hoc test runners for each PowerShell module. This works. Sort of. But it's still tiresome to run the tests selectively, and just as importantly, this doesn't fit into your CI/D setup which is geared towards your xUnit (or similar) test suites.

One quick and simple way to get around this issue is to write the tests in C# just as any other tests and simply call the PowerShell from there. Like so:

This isn't perfect:

  • It's somewhat slow. 
  • The call out to the PowerShell under test is tugged away inside a string.Format call
  • The tests and the code under test are written in different languages, which doesn't sit well with me. It introduces an odd asymmetry and it creates an artificial barrier between the tests and the code under test.
The big win on the other hand is that it fits right into your existing TDD and CI/D setup.