How to run a PowerShell script inside a Unit Test Method
Published Mar 13 2019 10:01 AM 5,313 Views
Iron Contributor
First published on MSDN on Aug 28, 2017

Authored by Gunjan Jain


Recently, a customer had the request of  creating sanity tests to validate driver builds they were working on against the latest builds from Microsoft. The scope of the tests needed to be high level, so Coded UI tests worked for the most part to drive the test from a UI level. Some tests, though, could not be engineered from a UI standpoint so a different approach was needed. For this, PowerShell fit the bill to drive the test from a lower level, and utilize WMI to access the needed components. An example of the functionality that needed to be validated is the enumeration of SD cards to validate the functionality of the USB drivers. After the tests were created and smoke tested in the PowerShell Interface, the task of figuring out how to implement the PowerShell into the existing test framework for the Coded UI tests was the next step.

The challenge of implementing the PowerShell code into the Unit Test is mitigated due to the libraries .NET has available to interface with PowerShell. The System.Management.Automation namespace contains the class PowerShell needed to create a PowerShell session, and ultimately run the code. To create the PowerShell runtime, following code was used:
PowerShell ps = PowerShell.Create();
This creates the PowerShell session to run the code. From here, a Script or a Command (among numerous options) can be added to execute. For the test created, a pre-defined script was used that would referenced during the test.
var script = GetScriptContents();
ps.AddScript(script);
To execute the script, call the Invoke method on the PowerShell session
ps.Invoke();

It returns a collection of PowerShell Object that can inspected for a specific return value. In this example, the Count property was evaluated to ensure the command executed successfully.

With the System.Management.Automation library, interfacing with PowerShell has been made magnitudes easier, and allows the flexibility of running already defined scripts within C# to promote code reuse. Below is the reference script in its entirety. For the file referenced from the Unit Test, it is a deployable file that resides in the same directory as the calling assembly. This allows the use of Reflection at runtime to grab the file and read the contents.

using Microsoft.VisualStudio.TestTools.UITesting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using System.Management.Automation;

namespace PS.Example
{

/// <summary>
/// Summary description for SDCard_Test_Win32
/// </summary>

[CodedUITest]
public class Example
{
PowerShell ps;

public Example()
{
ps = PowerShell.Create();
}

[TestInitialize]
public void Initialize()
{
var script = GetScriptContents();
ps.AddScript(script);
}

[TestMethod]
public void TestPowershell()
{
var objects = ps.Invoke();
if (objects.Count <= 0)
{
Assert.Fail("The Test has Failed.");
}
}

private string GetScriptContents()
{
var location = System.Reflection.Assembly.GetCallingAssembly().Location;
var scriptLocation = Path.GetDirectoryName(location) + "\\PowerShell_Test.ps1";
var script = File.ReadAllText(scriptLocation);
return script;
}

/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>

public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
private TestContext testContextInstance;
}
}


PowerShell Script Used:
Get-WmiObject -query "Select * from win32_logicaldisk where DriveType=2"

Version history
Last update:
‎Mar 13 2019 10:01 AM
Updated by: