0

I'm trying to write a pester test (v5) to see if various services are running on remote computers. This is what I have, which works:

$Hashtable = @(
        @{ ComputerName = "computer1"; ServiceName = "serviceA" }
        @{ ComputerName = "computer1"; ServiceName = "serviceB" }
        @{ ComputerName = "computer2" ; ServiceName = "serviceB" }

    )


Describe "Checking services" {

        It "check <ServiceName> is running on <ComputerName>" -TestCases $Hashtable {
            ( get-service -computername $ComputerName -name $ServiceName ).status | Should -be "Running" 
        }

} 

My question is around providing the test data to the test (i.e. the list of computer names and services). Suppose I want to add more services to this list. At the moment, I would be modifying my pester file by adding more services to $Hashtable. It doesn't feel quite right to be doing this to me, and I'd like to get the approach correct at this early stage. My gut tells me that the list of services should be separated from the pester file. Then running the test would involve importing the list of services somehow. Does anyone know if I am going about this the wrong way? Thanks for any help Andrew

Andy
  • 399
  • 1
  • 2
  • 10
  • Reading the list from a file sounds like an excellent idea :) Your question however ("Does anyone know if I am going about this the wrong way"), is likely to elicit opinions rather than facts, and as such is not really a good fit for StackOverflow. – Mathias R. Jessen May 09 '22 at 09:41
  • Agree this question is opinionated. An external file seems fine, another approach i've used in the past is to list everything in variables in a `BeforeAll` block at the top of the Pester script (before the first `Describe`), which at least keeps all the input values together and in one easy to see/maintain place. – Mark Wragg May 09 '22 at 09:51
  • Hi Mark and Mathias, apologies for the opinionated question. Point taken, and I will remember this for the future. – Andy May 09 '22 at 10:45

1 Answers1

0

If the list of servers and services will change often, it would be a good idea to read it from a separate file, especially if you have the tests under version control. This way you can easily see in the history that only the test data has changed, but the test logic didn't.

A good file format for the given test data would be CSV:

ComputerName, ServiceName
computer1, serviceA
computer1, serviceB
computer2, serviceB

You can read the CSV using Import-Csv, but you have to convert each row to a hashtable, because Pester expects an array of hashtables for the -TestCases parameter. Import-Csv outputs an array of PSCustomObject though.


BeforeDiscovery {
    $script:testCases = Import-Csv $PSScriptRoot\TestCases.csv | ForEach-Object {
        # Convert row (PSCustomObject) to hashtable.
        $hashTable = @{}
        $_.PSObject.Properties | ForEach-Object { $hashTable[ $_.Name ] = $_.Value }
        # Implicit output that will be captured in array $script:testCases
        $hashTable
    }
}

Describe "Checking services" {

    It "check <ServiceName> is running on <ComputerName>" -TestCases $script:testCases {
        ( get-service -computername $ComputerName -name $ServiceName ).status | Should -be "Running" 
    }
} 

Note: While not strictly necessary I have put the code that reads the test cases into the BeforeDiscovery section, as suggested by the docs. This makes our intentions clear.

zett42
  • 25,437
  • 3
  • 35
  • 72
  • 1
    Thanks a lot for that zett42 - that was really useful information. I've tried it and it works! Also, it's much easier to maintain a csv rather than a hashtable, particularly if there are more columns than what I have here. Thanks again – Andy May 09 '22 at 10:44