Scott Hanselman

Testing PowerShell scripts with NUnit

June 30, '06 Comments [4] Posted in PowerShell | NUnit
Sponsored By

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.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Friday, June 30, 2006 7:25:53 AM UTC
Scott,

I'm interested to know the kinds of things you are ending up doing with Monad.

I'm *trying* to use them mainly for adminy things. Stop service, start service, create virtual directories, the like.

If you are writing NUnit tests, I'm assuming you are using Monad as a more integral part of your solution.

Sachin
Sachin Rao
Friday, June 30, 2006 10:24:27 PM UTC
Wow, that looks just sooooo cool. I'm a fan of JPSofts' 4NT, looks like PowerShell has all the more and I'm looking forward to trying it out. Being able to run them as part of NUnit tests is just awesome.

Hey, and I just started listening to Hanselminutes with my new iPod Shuffle, very cool! I like the way you talk for a little bit, but not too long on topics. Lots of good info short and concise. Thanks Scott!
Wednesday, July 05, 2006 1:05:10 PM UTC
[Experimenting with a folksonomy]
PSMDTAG:FAQ: How do I test Scripts?
PSMDTAG:FAQ: Can I use NUNIT to test scripts?
PSMDTAG:SDK: RunspaceFactory.CreateRunspace(), CreatePipeline(), SessionStateProxy.SetVariable()

Jeffrey Snover [MSFT]
Windows PowerShell Architect
Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx
Jeffrey Snover
Thursday, July 06, 2006 3:29:56 AM UTC

typo alert!

myRunSpace.CreatePipeline(@"set-Location 'C:\dev\someproject");

has a missing single quote down near the end...

should be:

myRunSpace.CreatePipeline(@"set-Location 'C:\dev\someproject'");
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.