New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ScriptBlocks as advanced alternative to name templating for data-driven tests #2380
Comments
This could theoretically be done, but
There is an easy way to get this result, which is simply putting both Expected and AreEqual into the hashtable. Just for the geeks out there, but I don't recommend using this: You can also trick the code that does the re-evaluation of the string, by embedding a sub-expression, and have it evaluate any known function or your provided scripblock: See if you can figure out why it works from the escaping code here: The only downside there is that you get an extra Invoke-pester -container (new-pestercontainer -scriptblock {
BeforeDiscovery {
function Same ($Same){ $Same -eq "same" ? "`bTHE SAME" : "`bSOOO DIFFERENT" }
}
describe "a" {
It '<First> and <Second> return `$(Same <AreSame>) results' -ForEach @(
@{ First = 'Foo'; Second = 'Bar'; AreSame = 'same'; Eval = { param ($a) Write-Host -ForegroundColor Red "-$a-" } }
@{ First = 'Foo'; Second = 'Blergh'; AreSame = 'different' }
) {
# the test
}
It '<First> and <Second> return `$(& <Eval> <AreSame>) results' -ForEach @(
@{ First = 'Foo'; Second = 'Bar'; AreSame = 'same'; Eval = { param ($a) $a -eq "same" ? "`bTHE SAME" : "`bSOOO DIFFERENT" } }
@{ First = 'Foo'; Second = 'Blergh'; AreSame = 'different'; Eval = { param ($a) $a -eq "same" ? "`bTHE SAME" : "`bSOOO DIFFERENT" } }
) {
# the test
}
}
}) -Output Diagnostic
|
I think you misunderstood, I am proposing to pass the scriptblock into the # Old style
It 'Tests with <First> and <Second>' ...
# New style
It {"Tests with $First and $Second"} ... No new parameters are required, all Pester has to do is check the type of - $DisplayName = ProcessTemplate $Name $TestCase
+ if ($Name is [String]) {
+ $DisplayName = Process-Template $Name $TestCase
+ } else {
+ $Display Name = Invoke-Command $Name -ArgumentList $TestCase
+ } Maybe some other PowerShell magic will be required to pass the arguments without having to create |
An alternative idea with similar syntax is to add a parameter which instead of processing the template will just call It -ExpandName 'Tests with $First and $Second' ... I find it less elegant, as it requires extra parameter and use of single quotes to delay expansion, which may look weird and unintuitive. I don't really understand why Pester did not go into one of those approaches in the first place. It limits the templating to just variables and their children, and the hack you have shown indicates that it is possible to break out of this "sandbox" anyways. |
By same argument, you could just write the entire test name into an argument and use |
Checklist
Summary of the feature request
I often find myself compromising on the data I use with
-ForEach
/-TestCases
just to get more readable test names. For example:I would prefer to put into data just
Expected = $true
andExpected = $false
, but then I have no way of writing the test template to produce fully gramatical English sentence, as those do not support e.g. ternary operator. Trying to write something like'return <Expected ? "same" : "different">'
just fails to expand the template, or fails the discovery entirely.One idea I had to (hopefully) easily implement advanced templating without breaking changes is to allow the
Name
parameter to be a[ScriptBlock]
instead. If so, it can be called with all the parameters of the test case. Allowing the user to immediately return a string with full variable substitution should cover most of the cases in a compact way. For example, see below.How should it work?
The text was updated successfully, but these errors were encountered: