Reputation: 11
I write a module used for powershell-wrapping a commandline tool.
For my tests I had some variables defined in BeforeAll. Those vars should help in feeding the command with desired params and check them against the expected result, f.i.
BeforeAll {
$PORead=@{
Name = "Paul"
Permission ="Read"
Inheritance = "ThisFolderSubfoldersAndFiles"
}
$POReadExp="-bla bla (bla:bla;fra:fra;tra:tra)"
}
Now I want to use these in an it segment to feed the function and check the result, like:
It "checks result" -ForEach (
@{Param=$PORead;Expected=$POReadExp}
) {
$result=FunctionCall -Parameter1 $Param
$result | Should -Be $Expected
}
Note: This is actually no working code - just to make clear what I want.
The problem is, that $Param and $Expected are $null, thus the current value of $PORead and $POReadExp are not assigned to $Param and $Expected. I made it easy to demonstrate the problem - in my code I use arrays in the -ForEach hash assigned to $Param and $Expected.
Using plain strings, there is no problem and everything works fine. I could use plain text and than use som switch construct to match my strings with the according variables from BeforeAll{}, but I thought there must be a more elegant way.
Using standard hashtables, the variable substition works fine.
I'd appreciate any idea.
To clarify some things:
The solution of Mark works somehow, but it needs the $PORead and $POReadExp to be set outside the BeforeAll-block (if you want to use -ForEach), or within the BeforeAll-block, but in that case you only can use one argument.
My plan was a bit different, so I'm making my point a bit clearer:
In the BeforeAll-block I wanted a bunch of definitions for params and outcomes
BeforeAll {
$PORead = @{
Name = "Paul"
Permission ="Read"
Inheritance = "ThisFolderSubfoldersAndFiles"
$PODelete = @{
Name = "Paul"
Permission ="Delete"
Inheritance = "ThisFolderOnly"
}
$POReadResult = "add parameters"
$PODeleteResult = "delete parameters"
}
Now I want to test a whole bunch of combinations, feeding different combinations to the function and checking, if the combination of results match:
It "Test if all combinations works" -ForEach(
@{FunctionParam=$PORead;Expected=$POReadExp}
@{FunctionParam=$PORead,$PORead;Expected=$POReadExp,$POReadExp}
@{FunctionParam=$PORead,$PODelete,$PORead,$PORead;Expected=$PORead,$PORead,$PORead,$PODelete}
) {
$result = Function-Call -Param $FunctionParam
$wanted = $expected -join(" ")
$result | Should -Be $wanted
}
I can realize this by placing the definitions out of any block, but it feels wrong in terms of pester coding guidelines.
Greets Usul
Upvotes: 1
Views: 2822
Reputation: 707
You need to move your data used to generate tests from the BeforEach{} block to BeforeDiscovery{} block (see the linked pester documentation, has a really good simple example).
Pester needs your data that drives your DataDrivenTests to be available before it dynamically generates the test cases, so it knows how many to make.
BeforeAll{}/BeforeEach{} blocks should be reserved for data used after the It{} blocks are generated, but before they are evaluated.
Upvotes: 2
Reputation: 23395
The scopes for how to set test data with Pester v5 are quite confusing. What I've found is that anything you set in a BeforeAll
or BeforeEach
is available within the It
. However if you want to set values to the -ForEach
(or its alias -TestData
) you need to do it as part of or before the It
, outside of the BeforeEach
or BeforeAll
.
As such I think your tests will work if you do this:
$PORead = @{
Name = "Paul"
Permission ="Read"
Inheritance = "ThisFolderSubfoldersAndFiles"
}
$POReadExp = "-bla bla (bla:bla;fra:fra;tra:tra)"
It "checks result" -ForEach (
@{Param=$PORead;Expected=$POReadExp}
) {
$result=FunctionCall -Parameter1 $Param
$result | Should -Be $Expected
}
Or alternatively (if you just need to perform a single test):
BeforeAll {
$PORead=@{
Name = "Paul"
Permission ="Read"
Inheritance = "ThisFolderSubfoldersAndFiles"
}
$POReadExp="-bla bla (bla:bla;fra:fra;tra:tra)"
}
It "checks result" {
$result = FunctionCall -Parameter1 $PORead
$result | Should -Be $POReadExp
}
If you want to avoid using a variable that is not within one of the Pester code blocks, then you should do this (which is in line with the examples given in the Pester documentation on Data Driven Tests):
It "checks result" -ForEach (
@{
Param = @{
Name = "Paul"
Permission = "Read"
Inheritance = "ThisFolderSubfoldersAndFiles"
}
Expected = "-bla bla (bla:bla;fra:fra;tra:tra)"
}) {
$result=FunctionCall -Parameter1 $Param
$result | Should -Be $Expected
}
Upvotes: 2