From 0db87703ee4c5a5a4855edd62c39b76860561c06 Mon Sep 17 00:00:00 2001 From: nohwnd Date: Tue, 30 Jun 2026 19:39:10 +0200 Subject: [PATCH] Test stray output during a real run, not only Split-RSpecResult The two tests added in #2746 only exercised internals (Split-RSpecResult and the typed result list), so neither covered a real run that emits stray output. Replace the redundant one with an end-to-end Invoke-Pester run that leaks to the success stream from Run.BeforeContainer - the same path a stray native-command write takes - and assert the run completes with its results intact and a warning instead of crashing. Keep a focused Split-RSpecResult unit test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tst/Pester.RSpec.ts.ps1 | 54 ++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/tst/Pester.RSpec.ts.ps1 b/tst/Pester.RSpec.ts.ps1 index 9845f40fc..684551b9b 100644 --- a/tst/Pester.RSpec.ts.ps1 +++ b/tst/Pester.RSpec.ts.ps1 @@ -3336,6 +3336,40 @@ i -PassThru:$PassThru { } b 'Stray output during the run does not crash Pester (#2655)' { + t 'a real run with stray output finishes, keeps its results, and warns instead of crashing' { + # Reproduce the leak end-to-end the way it happens in the wild: something writes to the + # success stream while the run is in progress, so the stray value ends up in Invoke-Test's + # output next to the real [Pester.Container]. A BeforeContainer block is a reliable stand-in + # for the original trigger - an unredirected native command (winrm/net) in a setup block - + # which could not be reproduced deterministically. Before #2655 that stray object was added + # to the strongly-typed Run.Containers list and threw "Cannot find an overload for Add", + # taking down the whole run. + $sb = { + Describe 'd' { + It 'passes' { $true | Should -Be $true } + } + } + + $r = Invoke-Pester -Configuration ([PesterConfiguration]@{ + Run = @{ + ScriptBlock = $sb + PassThru = $true + BeforeContainer = { 'WinRM service is already running on this machine.' } + } + Output = @{ Verbosity = 'None' } + }) -WarningVariable warnings 3> $null + + # The run completed instead of crashing, and the real results came through untouched. + $r | Verify-NotNull + $r.Result | Verify-Equal 'Passed' + $r.Containers.Count | Verify-Equal 1 + $r.PassedCount | Verify-Equal 1 + $r.FailedCount | Verify-Equal 0 + + # The stray output was dropped with a warning that points at the likely cause. + ($warnings -join "`n") | Verify-Like "*unexpected output*WinRM service is already running on this machine.*" + } + t 'Split-RSpecResult keeps containers and collects stray output separately' { # Get a real [Pester.Container] to mix with stray output $real = Invoke-Pester -Configuration ([PesterConfiguration]@{ @@ -3356,26 +3390,6 @@ i -PassThru:$PassThru { $split.StrayOutput.Count | Verify-Equal 1 $split.StrayOutput[0] | Verify-Equal 'WinRM service is already running on this machine.' } - - t 'Run.Containers only receives containers after splitting, so the run does not crash' { - $real = Invoke-Pester -Configuration ([PesterConfiguration]@{ - Run = @{ ScriptBlock = { Describe 'd' { It 'i' { $true | Should -Be $true } } }; PassThru = $true } - Output = @{ Verbosity = 'None' } - }) - $container = $real.Containers[0] - - # Adding stray output straight to the strongly-typed list is what used to throw - # "Cannot find an overload for Add" and fail the whole run. - $threw = $false - try { ([Pester.Run]::Create()).Containers.Add('stray native output') } catch { $threw = $true } - $threw | Verify-True - - # After splitting, only the container is added and the run is built without error. - $run = [Pester.Run]::Create() - $split = & (Get-Module Pester) { param($c) Split-RSpecResult -Result (@($c, 'stray native output')) } $container - foreach ($i in $split.Containers) { $run.Containers.Add($i) } - $run.Containers.Count | Verify-Equal 1 - } } # Migrated from the removed Pester v4 suite TestsRunningInCleanRunspace.Tests.ps1,