PowerShellEditorServices: 'Run tests|Debug tests' Pester code lens does not show when Describe block is interpolated string
I sometimes include test details in the describe block that are sometimes only known at runtime, however, the Pester code lens does not show any more once I use an interpolated string in the Describe block.
Given the following Pester file (foo.tests.ps1
):
$version = $PSVersionTable.PSVersion.Major
Describe "foo on PSVersion $version" {
It "bar $version" {
}
}
The Run tests|Debug tests
code lens does not show, I see that under the hood, the extension creates parameters to Invoke-Pester
that look like -PesterOption @{IncludeVSCodeMarker=$true} -TestName 'foo'
, in this case, the extension would either need to evaluate the interpolated string or just get rid of the -TestName
parameter.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 22 (8 by maintainers)
Commits related to this issue
- Fix #827 Pester TestName w/expandable str returns nothing This update will return null to indicate that the TestName arg was present but not something we could evaluate. The extension will see the n... — committed to PowerShell/PowerShellEditorServices by rkeithhill 5 years ago
- Revert "Fix #827 Pester TestName w/expandable str returns nothing (#851)" This reverts commit 161a3ed45fafacfc225d3bc335cd6f5e84a255e5. — committed to bergmeister/PowerShellEditorServices by bergmeister 5 years ago
- Revert "Revert "Fix #827 Pester TestName w/expandable str returns nothing (#851)"" This reverts commit f26755f8aecd434c45d05631ee4d4ee8c2833476. — committed to bergmeister/PowerShellEditorServices by bergmeister 5 years ago
@rkeithhill it does not, yet. If I have some time I will code it for 4.5.1 over the weekend
We had a specific bug we fixed by changing to single quotes. I’d rather not have a regression in this case. It may be necessary to provide info from PSES back to the extension indicating whether we have string constant expr in which case we use single quotes or an expandable string in which case we could use double quotes. But again, as @SeeminglyScience and I came to the conclusion that in likely many cases the variable required to be interpolated will not be defined in the PS integrated console at the time of the first run and maybe even not for subsequent runs. I think having a feature that partialy works (in certain scenarios) does not make for a good user experience. All in all, I think it is better to stick with single quoting and skip attempting to handle expandable strings - other then to display an error in VSCode when the associated code lens is invoked.
@rkeithhill if it doesn’t, we can just still show the codelens and have it display an error when clicked if there’s no way to, on the fly, change it to an error
I’d say do add the code lens, but write a descriptive error message. A rule works too I suppose but that’s more default stuff folks would need to suppress.
From what I gather here (and @nohwnd please confirm if you haven’t already) having parameters inside of the string is not a best practice since test strings should be static.
This helps make tests less cryptic and also helps us out because we have a best practice to depend on. This also means that we (the extension) can help enforce the best practice.
What if we do this:
Add a
Run all tests
CodeLens to the top of the file. This helps @bergmeister with a button that will run all the tests.We don’t add CodeLens to Describes with variables in them
We add a PSSA rule that warns to “not have variables in test names”
We enforce a best practice, but still give users the ability to click a button to run tests
@bergmeister do you want to try implementing this so it filters on path+line? The implementation in Pester should be very simple (plus you already know the codebase), and you’d get some practice in TS. I’d accept a PR for it.
Playing with this a bit more:
There’s no way to execute the test with
Invoke-Pester ./My.Tests.ps1 -TestName <name>
here without knowing what the value of$duck
is statically. To make Pester execute it, we needInvoke-Pester ./My.Tests.ps1 -TestName 'My test Hello'
. Since the CodeLens execute button is executed outside of the file, we can’t just ever make it work in general – and I think it’s worth noting that this is a limitation that exists for Pester without our CodeLens too (not saying it should work, just that the problem is one of expecting runtime information to be known statically).Circling back to the original problem statement:
I think “only known at runtime” defines this problem as out of scope for something based on AST analysis. If it’s only known at runtime, then there’s no way for us to ask Pester to execute this.
Yes, there is v5-alpha1 since yesterday that can discover tests and filter them by
It
, and only run appropriate setups and teardowns, so it should be ideal for running tests selectively.It already can filter by path, you can see me do someting very similar with re-running failed tests here.
At the moment those published functions do not take the result object + paths (to keep the api smaller and simpler), instead test discovery is done every time from scratch.
But internally the limitation is not there, if I add functions that clean a dirty discover/run result, it could easily take a cached discovery object and run with different filters. Which is useful not only for this scenario, but for example if you want to observe filesystem, discover tests in a single file, join that discovery result to your cached results and re-run all previously failed tests in all files. Or when you have a huge test suite where discovery takes signifcant amount of time, and multiple configurations to run it with.
I’m still very uneasy about the idea of some of the code lenses running all tests and some running only the nearest
describe
block. I’d much rather see a descriptive error message explaining that the test name should be static.It’s probably not a huge deal for just
describe
s, but ideally we’d support a code lens for everyit
block. I believe @nohwnd mentioned filtering byit
block names is potentially coming in the next major release.Interestingly the single quote is by design, which this issue documents as it used to be double quotes but was not working for interpolated strings in special scenarios where
ToString()
was resulting in something that Pester could not understand, maybe this is also an issue with Pester… Maybe the better solution is to just runInvoke-Pester
without the-TestName
(i.e. on the whole file) if theDescribe
string contains a dollar signWhat if we created the command line using double quotes e.g.
-PesterOption @{IncludeVSCodeMarker=$true} -TestName "foo on PSVersion $version"
? Or maybe, if we can pull the string from the Describe block, it would be better to use that string quoting. That way if you used single quotes to prevent interpolation, we’d honor that.