pester / vscode-adapter

Run PowerShell Pester Tests with Visual Studio Code
MIT License
58 stars 13 forks source link

variable expansion not working in BeforeAll or BeforeEach blocks #195

Closed kevball2 closed 1 year ago

kevball2 commented 1 year ago

When running the following tests, the value is never expanded in Test Explorer. The tests run properly when using invole-pester. Even if I set a static value for the title it will not show up in the test explorer pane.</p> <pre><code class="language-powershell"># Discovers testing files BeforeDiscovery { $files = Get-ChildItem '.\Definitions\policyDefinitions' -Recurse -Include *.json, *.jsonc } # Expect multiple json in a loop, could be folder or file # Print file name for each Describe "Testing Policy Definition <title> " -ForEach $files { BeforeAll { $title='' $testJson = Get-Content $_.FullName -raw -ErrorAction SilentlyContinue if($(test-json $testJson)) { $title = (Get-Content $_ | ConvertFrom-Json).name } } It "Json file <title> should be properly formatted" { $title | Should -Not -BeNullOrEmpty } } </code></pre> <p><img referrerpolicy="no-referrer" src="https://github.com/pester/vscode-adapter/assets/22545150/a125c011-4ce3-46e4-a1f4-71647d443811" alt="image" /></p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/JustinGrote"><img src="https://avatars.githubusercontent.com/u/15258962?v=4" />JustinGrote</a> commented <strong> 1 year ago</strong> </div> <div class="markdown-body"> <p>@kevball2 confirmed, I simplified your example:</p> <pre><code class="language-powershell"># Discovers testing files BeforeDiscovery { $titles = 'a', 'b', 'c' } # Expect multiple json in a loop, could be folder or file # Print file name for each Describe 'Testing Title <title> ' -ForEach $titles { BeforeAll { $title = $_ } It 'Title <title>' {} }</code></pre> <p>We pull our titles from Pester, so this interpolation may be happening in Pester after our step in the process.</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/JustinGrote"><img src="https://avatars.githubusercontent.com/u/15258962?v=4" />JustinGrote</a> commented <strong> 1 year ago</strong> </div> <div class="markdown-body"> <p>Your test formatting is kind of strange, looks like you are using named references (which refer to the properties on hashtables), and just by some quirk this works in Pester at the final output, but you are generating the "title" inside of the test, so it doesn't surprise me it doesn't discover correctly.</p> <p>In order to do a named test with a named reference, you are supposed to use hashtables, it does not work with just objects: <a href="https://pester.dev/docs/usage/data-driven-tests">https://pester.dev/docs/usage/data-driven-tests</a></p> <p>Try structuring your test this way:</p> <pre><code class="language-powershell"># Discovers testing files BeforeDiscovery { $files = Get-ChildItem "$PSScriptRoot/Mocks/PolicyDefinitions" -File -Recurse -Include *.json, *.jsonc $testCases = $files | ForEach-Object { @{ File = $_ Name = $_.BaseName } } } # Expect multiple json in a loop, could be folder or file # Print file name for each Describe 'Testing Policy Definition <name>' -ForEach $testCases { BeforeAll { $policy = Get-Content $file.FullName -Raw | ConvertFrom-Json -ErrorAction Stop } It 'should have a Name' { $policy.name | Should -Not -BeNullOrEmpty } }</code></pre> <p>This works for me and has the desired result: <img src="https://github.com/pester/vscode-adapter/assets/15258962/e74ce41d-0e67-4929-96b6-08cd205149b0" alt="image" /></p> <p>So unless I'm missing something, I'm going to close this as "wontfix" because it's not supported by Pester directly and it only works in your case probably due to a quirk.</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/JustinGrote"><img src="https://avatars.githubusercontent.com/u/15258962?v=4" />JustinGrote</a> commented <strong> 1 year ago</strong> </div> <div class="markdown-body"> <p>Here's an alternative array syntax, which will ToString the file and give you the full filename, which doesn't look like what you want but I'm putting it here for posterity</p> <pre><code class="language-powershell"># Discovers testing files BeforeDiscovery { $files = Get-ChildItem "$PSScriptRoot/Mocks/PolicyDefinitions" -File -Recurse -Include *.json, *.jsonc } # Expect multiple json in a loop, could be folder or file # Print file name for each Describe 'Testing Policy Definition <_>' -ForEach $files { BeforeAll { $policy = Get-Content $_ -Raw | ConvertFrom-Json -ErrorAction Stop } It 'should have a Name' { $policy.name | Should -Not -BeNullOrEmpty } }</code></pre> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/kevball2"><img src="https://avatars.githubusercontent.com/u/22545150?v=4" />kevball2</a> commented <strong> 1 year ago</strong> </div> <div class="markdown-body"> <blockquote> <p>Your test formatting is kind of strange, looks like you are using named references (which refer to the properties on hashtables), and just by some quirk this works in Pester at the final output, but you are generating the "title" inside of the test, so it doesn't surprise me it doesn't discover correctly.</p> <p>In order to do a named test with a named reference, you are supposed to use hashtables, it does not work with just objects: <a href="https://pester.dev/docs/usage/data-driven-tests">https://pester.dev/docs/usage/data-driven-tests</a></p> <p>Try structuring your test this way:</p> <pre><code class="language-powershell"># Discovers testing files BeforeDiscovery { $files = Get-ChildItem "$PSScriptRoot/Mocks/PolicyDefinitions" -File -Recurse -Include *.json, *.jsonc $testCases = $files | ForEach-Object { @{ File = $_ Name = $_.BaseName } } } # Expect multiple json in a loop, could be folder or file # Print file name for each Describe 'Testing Policy Definition <name>' -ForEach $testCases { BeforeAll { $policy = Get-Content $file.FullName -Raw | ConvertFrom-Json -ErrorAction Stop } It 'should have a Name' { $policy.name | Should -Not -BeNullOrEmpty } }</code></pre> <p>This works for me and has the desired result: <img src="https://user-images.githubusercontent.com/15258962/266090160-e74ce41d-0e67-4929-96b6-08cd205149b0.png" alt="image" /></p> <p>So unless I'm missing something, I'm going to close this as "wontfix" because it's not supported by Pester directly and it only works in your case probably due to a quirk.</p> </blockquote> <p>Thanks for the feedback @JustinGrote! I was trying to reproduce the example from the pester documentation for the newer format for data driven tests - <a href="https://pester.dev/docs/usage/data-driven-tests#another-variation-on-foreach">https://pester.dev/docs/usage/data-driven-tests#another-variation-on-foreach</a> . Their example made me think it would be possible to set the title variable in the beforeAll block but that doesn't appear to work. In this instance the file name is all I wanted for the root test name so your example here creating the test cases does the job nicely. </p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/kevball2"><img src="https://avatars.githubusercontent.com/u/22545150?v=4" />kevball2</a> commented <strong> 1 year ago</strong> </div> <div class="markdown-body"> <p>Resolving issue: Solution for this issue was to create test cases in the BeforeDiscovery block that can be passed to the Describe block.</p> </div> </div> <div class="page-bar-simple"> </div> <div class="footer"> <ul class="body"> <li>© <script> document.write(new Date().getFullYear()) </script> Githubissues.</li> <li>Githubissues is a development platform for aggregating issues.</li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script> <script src="/githubissues/assets/js.js"></script> <script src="/githubissues/assets/markdown.js"></script> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.4.0/build/highlight.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.4.0/build/languages/go.min.js"></script> <script> hljs.highlightAll(); </script> </body> </html>