Search code examples
powershellcollectionspester

Assertion over each item in collection in Pester


I am doing some infrastructure testing in Pester and there is repeating scenario that I don't know how to approach.

Let's say, I want to check whether all required web roles are enabled on IIS. I have a collection of required web roles and for each of them I want to assert it is enabled.

My current code looks like this:

$requiredRoles = @(
    "Web-Default-Doc",
    "Web-Dir-Browsing",
    "Web-Http-Errors",
    "Web-Static-Content",
    "Web-Http-Redirect"
)

Context "WebRoles" {

    It "Has installed proper web roles" {

        $requiredRoles  | % {
            $feature = Get-WindowsOptionalFeature -FeatureName $_ -online
            $feature.State | Should Be "Enabled"
        }
    }
}

It works in the sense that the test will fail if any of the roles are not enabled/installed. But that is hardly useful if the output of such Pester test looks like this:

Context WebRoles
[-] Has installed proper web roles 2.69s
  Expected: {Enabled}
  But was:  {Disabled}
  283:                 $feature.State | Should Be "Enabled" 

This result doesn't give any clue about which feature is the Disabled one.

Is there any recommended practice in these scenarios? I was thinking about some string manipulation...

Context "WebRoles" {

    It "Has installed proper web roles" {

        $requiredRoles  | % {
            $feature = Get-WindowsOptionalFeature -FeatureName $_ -online
            $toCompare = "{0}_{1}" -f $feature.FeatureName,$feature.State 
            $toCompare | Should Be ("{0}_{1}" -f $_,"Enabled")
        }
    }
 }

which would output:

Context WebRoles
[-] Has installed proper web roles 2.39s
  Expected string length 27 but was 28. Strings differ at index 20.
  Expected: {IIS-DefaultDocument_Enabled}
  But was:  {IIS-DefaultDocument_Disabled}
  -------------------------------^
  284:                 $toCompare | Should Be ("{0}_{1}" -f $_,"Enabled")

...which is better, but it doesn't feel very good...

Also, there is second problem with the fact that the test will stop on first fail and I would need to re-run the test after I fix each feature...

Any ideas?


Solution

  • Put your It inside the loop like so:

    Context "WebRoles" {
      $requiredRole | ForEach-Object {
        It "Has installed web role $_" {
          (Get-WindowsOptionalFeature -FeatureName $_ -online).State | Should Be "Enabled"
        }
      }  
    }