UnitTesting In PowerShell

Do you have a PowerShell module or script with nice PowerShell functions and want to get them under a test-harness ? Do you want to write unittests for your functions and need a testrunner?

Than this is the right place to search for your needs! We show you a module that provides the functions for unittesting, and we give you the PowersShell-Testrunner. The output will look like this:

16-01-2014 14-16-53

Here is an example:

$updatedFile = Update-VaultFile -File "$/Test/Test.ipt" -Status "For Review"

This is a function that is able to update the status of a file in Vault. It returns the updated file. Would it not be nice to write a test for this function ? If you have the correct test in place, and you do changes in your function Update-VaultFile, you can be sure that this functionality is not destroyed or affected by the changes!

Now what you could do, is writing the test like this:

 if($updatedFile.State -ne "For Review"){
   throw("Status for file Test.ipt is not updated!")
 }

This would work, but it is three lines of code, just because of one simple assertion. We could use the powerful unittesting-framework NUnit instead. But how can we do that?

I did the work for you and created a module that can be imported in your PowerShell session. Then you can use its functionalities and extend them very easily!

Here we go with the test from before:

$updatedFile.State.ShouldBeEqual( "For Review")

We can go on asserting like this:

$updatedFile.Version.ShouldNotBeEqual( 1 )

You see that our functions are available for all the objects you want: for integers, for strings, for lifecycles, for dateTimes, …

It’s incredible, but we attached this functions on all the objects derived from System.Objects!

Open the file cONunitPowerShellExtension.ps1xml and you will see how easy it is to create new functions, by just defining them in the xml structure. The definition of the function ShouldBeEqual looks like this:

<ScriptMethod>
  <Name>ShouldBeEqual</Name>
  <Script>
    [NUnit.Framework.Assert]::AreEqual($args[0], $this, $args[1])
  </Script>
</ScriptMethod>

By calling ShouldBeEqual, that Nunint-framework functionality Assert.AreEqual will be called and if the assertion is false, it will throw automatically the exception.

Now you have the framework up and running, but how can you write tests and execute them?

If you need a testrunner for your tests use this code:

function GetAllTestFunctions {
  gci function: | where {$_.Name.StartsWith("Test_") -and $_.Definition.StartsWith("param()") }
}

$passed =0
$failed =0
$allTestFunction = GetAllTestFunctions
foreach ( $testFunction in $allTestFunction) {
  try {
    Invoke-Expression -Command $testFunction.Name
    Write-Host "$($testFunction.Name)" -BackgroundColor Green
    $passed++
 } catch {
   $exc = $_.Exception
   Write-Host "$($testFunction.Name)" -BackgroundColor Red
   Write-Host $exc
   $failed++
 }
}
Write-Host
Write-Host "Passed: $($passed)"
Write-Host "Failed: $($failed)"
Write-Host "Total: $($passed+$failed)"

Place this code in some ps1 script and define your unittest-functions like this:

function Test_FileStatusIsUpdatedToForReview()
{
 $updatedFile = Update-VaultFile -File "$/Test/Test.ipt" -Status "For Review"
 $updatedFile.State.ShouldBeEqual( "For Review")
}
function Test_FileStatusIsNotUpdatedWhenPassingWrongState()
{
 $updatedFile = Update-VaultFile -File "$/Test/Test.ipt" -Status "Some wrong status"
 $updatedFile.State.ShouldNotBeEqual( "Some wrong status")
}

Just place functions without parameters where the function name starts with “Test_”, and the PowerShell-Testrunner will execute them for you.

The result looks like the result of other testrunners :

16-01-2014 13-01-23

If you are interested, just download cONunitPowerShellExtension and extract the module to one of your PowerShell-module directories (a.e. C:\Windows\System32\WindowsPowerShell\v1.0\Modules).

Import the module with  “Import-Module cONunitPowerShellExtension” and feel free to extend the ps1xml-file with other more powerful functionality from the NUnit framework.

I wish you a nice unittesting and that all your tests are passing ;)

About weiss92

Software Developer
This entry was posted in Data Standard, powerJobs, PowerShell, Uncategorized and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s