Saturday, February 7, 2015

Introducing FluentShellUnit - A unit testing framework for PowerShell in C#

FluentShellUnit is a unit testing framework of testing PowerShell scripts and modules. It provides a simple to use API to write your tests in C# for loading and executing the functions in a PowerShell module or script file. It follows a very easy approach to stub the existing cmdlets or functions so that you can easily isolate your test code. This makes it a very good candidate for teams practicing TDD and using PowerShell in their code base.

Using the framework:

You can download the entire source code from the GitHub repository or use the Nuget package that is available from the Nuget gallery in Visual studio.
To download the source code and compile it to use in you projects visit the GitHub page at https://github.com/prajeeshprathap/FluentShellUnit.
To download the nuget package, open the package download manager from visual studio and search for FluentShellUnit. Click install to install the package to your project.

Creating your first test.

Create a new Unit test project in C# and a new test class to the project
Use the DeploymentItem attribute in the class to deploy the PowerShell modules to the test execution local folder if you don’t want to refer the modules from a fixed location in your drive. This approach will ensure that the modules are not loaded from an absolute path on the developer’s machine that created the tests. With the use of DeploymentItem you can also ensure that, the tests will work fine in the build server as well.

[TestClass]
[DeploymentItem(@"Data\Modules\Host\Host.psm1""Modules")]
public class HostTests

Create a test method and ues the PsFactory.Create method to create a new intsance of the PowerShell host that allows you to load and execute tests.
[TestClass]
[DeploymentItem(@"Data\Modules\Host\Host.psm1""Modules")]
public class HostTests
{
    [TestMethod]
    [TestCategory("Host Module")]
    public void ConfirmLocalSession_should_return_true_if_tests_are_executed_in_the_local_machine()
    {
        var actual = PsFactory.Create(HostState.Core);                   
    }
}

The load method will load a module into the runspace from a path mentioned as parameter to the method. If you have not used the DeploymentItem attribute, then you can make use of the IsAbsolute overload of the method and pass the absolute path instead of a relative path.
var actual = PsFactory.Create(HostState.Core)
            .Load(@"Modules\Host.psm1");          

To execute a method from the loaded module call the Execute method with the method name. The example show in this sample is calling a method that does not except any parameters. We’ll see later how to pass parameters to the method if needed.

var actual = PsFactory.Create(HostState.Core)
            .Load(@"Modules\Host.psm1")
            .Execute("Confirm-LocalSession");

Finally the ResultAs and FirstResultitemAs methods will tanslate the result of execution into a type mentioned and can be used for assertions in the code.
var actual = PsFactory.Create(HostState.Core)
            .Load(@"Modules\Host.psm1")
            .Execute("Confirm-LocalSession")
            .FirstResultItemAs<bool>();

        Assert.IsTrue(actual);

No comments: