Skip to content

Also fail on Pester block/container failures (not just failed tests)#128

Merged
tablackburn merged 2 commits into
psake:mainfrom
nohwnd:fix/pester5-count-blocks-containers
Jul 7, 2026
Merged

Also fail on Pester block/container failures (not just failed tests)#128
tablackburn merged 2 commits into
psake:mainfrom
nohwnd:fix/pester5-count-blocks-containers

Conversation

@nohwnd

@nohwnd nohwnd commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

⚠️ This PR was generated by an AI agent (GitHub Copilot CLI). Please review accordingly.

I've been seeing this commonly across Pester 5 build scripts and I'm fixing it where it looks like it could hide real failures.

In Pester 5 a run reports three independent failure counts:

  • FailedCount — failed tests (It)
  • FailedBlocksCount — failed BeforeAll / AfterAll
  • FailedContainersCount — files that error during discovery / fail to load

Gating on only FailedCount means a BeforeAll that throws, or a test file that fails to load, leaves FailedCount = 0 and the build passes green despite real failures. Pester itself derives the overall pass/fail from the sum of all three.

This change includes all three counts in the gate. Display/log messages are left unchanged.

In Pester 5 a run has three independent failure counts. Gating only on
FailedCount misses FailedBlocksCount (BeforeAll/AfterAll) and
FailedContainersCount (files that fail to discover/load), so a failing
BeforeAll or an unloadable test file passes the build green. This adds
those counts to the gate.

Generated with AI (GitHub Copilot CLI).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tablackburn

Copy link
Copy Markdown
Contributor

@nohwnd should we also make this change to

if ($testResult.FailedCount -gt 0) {
?

@nohwnd

nohwnd commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Yes. You can also check the result property.

@tablackburn

Copy link
Copy Markdown
Contributor

@nohwnd do you want to include that change in this PR or do you want me to take care of it? I'm good either way.

tablackburn pushed a commit that referenced this pull request Jul 7, 2026
Test-PSBuildPester gated only on FailedCount, so a BeforeAll/AfterAll
that threw or a test file that errored during discovery left the count
at zero and the build passed despite tests never running. Gate on the
run's aggregate Result property instead, which Pester derives from all
failure categories (failed tests, failed blocks, failed containers).

This applies the shipped-function half of the fix discussed in #128;
that PR covers the repository's own psakeFile.ps1.

Verified against crash fixtures: a discovery-crash file yields
FailedCount=0 / Result=Failed and now throws; a BeforeAll crash still
throws; a healthy suite still passes. Full suite: 301 passed, 0 failed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011semwa5HU1BUKKL4RoWjKa

@tablackburn tablackburn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix! This is correct for the repo's own build file, and we've verified the bug class is real here — while migrating this repo's test suite to Pester 6 (#132), a test file died during discovery and the build still reported success (FailedCount=0, Container failed: 1, exit 0).

Per the discussion above, the shipped-function half (Test-PSBuildPester.ps1) is now covered in #133 using the Result property you suggested, so this PR can stay scoped as-is. Left one optional inline suggestion if you'd like the two gates to match.


Generated by Claude Code

Comment thread psakeFile.ps1
tablackburn pushed a commit that referenced this pull request Jul 7, 2026
Address review feedback on #133: the Unreleased entry linked #128, but
this change lands via #133. Point the entry at #133 and note the
companion relationship to #128 explicitly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011semwa5HU1BUKKL4RoWjKa
@tablackburn tablackburn merged commit f59efcc into psake:main Jul 7, 2026
6 checks passed
tablackburn pushed a commit that referenced this pull request Jul 7, 2026
Replace the three-counter sum merged in #128 with the aggregate Result
property, matching the gate in Test-PSBuildPester. Same behavior, one
source of truth for what "failed" means. Suggested by nohwnd in the
#128 discussion.

Verified both directions locally: a discovery-crash container fails the
build (exit 1), and a healthy run under Pester 5.8.0 passes (301
passed, exit 0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011semwa5HU1BUKKL4RoWjKa
tablackburn added a commit that referenced this pull request Jul 7, 2026
Test-PSBuildPester gated pass/fail only on FailedCount, so a
BeforeAll/AfterAll that threw or a test file that errored during
discovery left the count at zero and the build passed despite tests
never running. Gate on the run's aggregate Result property instead,
which Pester derives from all failure categories.

Also switch this repo's own psakeFile.ps1 Pester gate (the
three-counter sum from #128) to the same Result check so both gates
share one definition of "failed".

Companion to #128. Same bug lineage as #31, #52, and #57.
@nohwnd

nohwnd commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for merging, because see you using Claude here, just pointing out there is now skill for v6 migration, as well as for should -* to should-* migration.

https://pester.dev/docs/migrations/v5-to-v6#migrate-with-an-ai-assistant

tablackburn pushed a commit that referenced this pull request Jul 10, 2026
Add tests/Test-PSBuildPester.tests.ps1 (#102).
Every invocation runs in a Start-Job subprocess with a pinned inner
Pester version, and the scenarios run against both installed Pester
majors (5.x and 6.x) to verify the shipped function keeps supporting
Pester 5 consumers. Crash fixtures are generated into $TestDrive at
runtime, never checked in. Scenarios: healthy suite, failing test
(regression #52), BeforeAll crash and discovery crash (#128/#133 gate),
NUnit result output, and code coverage output path/format (regression
Add a second, named Pester dependency (PesterLegacy, 5.9.0) to
requirements.psd1 so CI installs both majors side by side.

Fix two latent Test-PSBuildPester bugs the tests exposed, test-first
(all 14 tests failed before the fixes, pass after):

- The finally block called Remove-Module with an empty -Name when the
  optional ModuleName parameter was omitted, raising a parameter-
  binding error that -ErrorAction SilentlyContinue cannot suppress.
- An unconditional Import-Module Pester -MinimumVersion 5.0.0 loaded
  the newest installed Pester on top of an already-loaded one, which
  crashes with a Pester.dll version conflict when two versions are
  installed side by side. The function now respects a loaded Pester
  (with a clear error below 5.0.0) and imports the newest installed
  version only when none is loaded.

Closes #102

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011semwa5HU1BUKKL4RoWjKa
tablackburn added a commit that referenced this pull request Jul 10, 2026
)

Add tests/Test-PSBuildPester.tests.ps1 (#102). Every invocation runs
in a Start-Job subprocess with a pinned inner Pester version, and the
scenarios run against both installed Pester majors (5.x and 6.x) to
verify the shipped function keeps supporting Pester 5 consumers. Crash
fixtures are generated into $TestDrive at runtime, never checked in.
Scenarios: healthy suite, failing test (regression #52), BeforeAll
crash and discovery crash (#128/#133 gate), NUnit result output, and
code coverage output path/format (regression #62).

Pester 5.9.0 is installed side by side with 6.0.0 through the new
install-only requirements.pester-matrix.psd1; the bootstrap must not
import it, because importing two Pester majors into one session
crashes with a Pester.dll version conflict.

Fix two latent Test-PSBuildPester bugs the tests exposed, test-first:

- The finally block called Remove-Module with an empty -Name when the
  optional ModuleName parameter was omitted, raising a parameter-
  binding error that -ErrorAction SilentlyContinue cannot suppress.
- An unconditional Import-Module Pester -MinimumVersion 5.0.0 loaded
  the newest installed Pester on top of an already-loaded one. The
  function now respects a loaded Pester (with a clear error below
  5.0.0) and imports the newest installed version only when none is
  loaded.

Closes #102
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants