We've been doing lots of PowerShell at work, but we're also a continuous integration shop and we try to do TDD so testing, specifically NUnit, is very important to us.
Here's how Jason Scheuerman from my team tests PowerShell scripts with NUnit.
using System;using System.Collections;using System.Collections.ObjectModel;using System.Management.Automation.Runspaces;using System.Management.Automation;using NUnit.Framework;using System.Security;
namespace PSUnitTestLibrary.Test{ [TestFixture] public class Program { private Runspace myRunSpace; [TestFixtureSetUp] public void PSSetup() { myRunSpace = RunspaceFactory.CreateRunspace(); myRunSpace.Open(); Pipeline cmd = myRunSpace.CreatePipeline(@"set-Location 'C:\dev\someproject"); cmd.Invoke(); }
[Test] public void PSTest() { Pipeline cmd = myRunSpace.CreatePipeline("get-location"); Collection<PSObject> resultObject = cmd.Invoke(); string currDir = resultObject[0].ToString(); Assert.IsTrue(currDir == @"'C:\dev\someproject");
cmd = myRunSpace.CreatePipeline(@".\new-securestring.ps1 password"); resultObject = cmd.Invoke(); SecureString ss = (SecureString)resultObject[0].ImmediateBaseObject; Assert.IsTrue(ss.Length == 8);
myRunSpace.SessionStateProxy.SetVariable("ss", ss); cmd = myRunSpace.CreatePipeline(@".\getfrom-securestring.ps1 $ss"); resultObject = cmd.Invoke(); string clearText = (string)resultObject[0].ImmediateBaseObject; Assert.IsTrue(clearText == "password"); } }}
The "CreatePipeline" calls are us telling PowerShell "do that!" The Pipeline of commands is created, passed into cmd then Invoke'd.
Also in this case we're assuming one PowerShell RunSpace per TestFixture and we're using the TestFixtureSetUp method to get that RunSpace going, but you could certainly move things around if you wanted different behavior or isolation.