Found while migrating PowerShell/PowerShell tests to Pester 5 (PR PowerShell/PowerShell#27290). If a container has more than one BeforeAll (or BeforeEach / AfterEach / AfterAll), only the last one runs. The earlier ones are discovered and silently dropped.
Repro on 5.7.1:
Describe "multi-hooks" {
BeforeAll { Write-Host "BA1" }
BeforeAll { Write-Host "BA2" }
BeforeEach { Write-Host " BE1" }
BeforeEach { Write-Host " BE2" }
AfterEach { Write-Host " AE1" }
AfterEach { Write-Host " AE2" }
AfterAll { Write-Host "AA1" }
AfterAll { Write-Host "AA2" }
It "i" { Write-Host " It" }
}
Prints BA2, BE2, It, AE2, AA2. The *1 blocks never run.
Mechanism is plain assignment in src/Pester.Runtime.ps1 - New-OneTimeTestSetup does .CurrentBlock.OneTimeTestSetup = , same for New-OneTimeTestTeardown, New-EachTestSetup, New-EachTestTeardown. Last writer wins. The Block type holds a single ScriptBlock per hook, not a list.
This bit a lot of files in the PowerShell repo migration - about -1255 failures across CI once the duplicate blocks were merged. The failure mode is silent: helper functions/variables defined in the earlier block simply aren't there at runtime, and the test fails with CommandNotFoundException or "argument is null" in It.
Idea
Either:
- Run all blocks of the same hook in source order (append to a list), or
- Fail discovery with a clear error when more than one is found in the same container.
(2) is the smaller change and would have caught all the cases I just fixed. (1) matches what people coming from xUnit/NUnit-style multiple setup methods would expect, and it's what the current docs imply.
Found while migrating PowerShell/PowerShell tests to Pester 5 (PR PowerShell/PowerShell#27290). If a container has more than one BeforeAll (or BeforeEach / AfterEach / AfterAll), only the last one runs. The earlier ones are discovered and silently dropped.
Repro on 5.7.1:
Prints
BA2,BE2,It,AE2,AA2. The*1blocks never run.Mechanism is plain assignment in
src/Pester.Runtime.ps1-New-OneTimeTestSetupdoes.CurrentBlock.OneTimeTestSetup =, same forNew-OneTimeTestTeardown,New-EachTestSetup,New-EachTestTeardown. Last writer wins. TheBlocktype holds a singleScriptBlockper hook, not a list.This bit a lot of files in the PowerShell repo migration - about -1255 failures across CI once the duplicate blocks were merged. The failure mode is silent: helper functions/variables defined in the earlier block simply aren't there at runtime, and the test fails with
CommandNotFoundExceptionor "argument is null" inIt.Idea
Either:
(2) is the smaller change and would have caught all the cases I just fixed. (1) matches what people coming from xUnit/NUnit-style multiple setup methods would expect, and it's what the current docs imply.