mirror of
https://github.com/kellymichels/zscripts-token-savers
synced 2026-10-07 07:18:18 +00:00
test(coverage): run the Pester suite with code coverage
tests/Invoke-Coverage.ps1 runs the suite with Pester's profiler-based coverage collector and writes both JaCoCo XML and a coverage-summary.json in the same shape vitest and jest emit, so one reader handles every tool in the fleet. CodeCoverage.Path is every *.ps1 in the repo root, including the ones no test touches. They report 0% and drag the total down, which is correct - measuring only the already-tested files answers "how well covered is the covered code". The same mistake in vitest form had evo.www reporting 93%. Baseline: 222 tests pass, 7.0% of commands (219/3,125 across 24 scripts). Pester counts commands, not statements; the collector labels it as such rather than filing it under a unit it is not.
This commit is contained in:
parent
5701dff60a
commit
c13aed235b
3
.gitignore
vendored
3
.gitignore
vendored
@ -16,3 +16,6 @@ desktop.ini
|
||||
|
||||
# Internal working notes (superseded by TOKEN_SAVINGS.md)
|
||||
md/
|
||||
|
||||
# Pester coverage output (regenerated; never committed)
|
||||
coverage/
|
||||
|
||||
91
tests/Invoke-Coverage.ps1
Normal file
91
tests/Invoke-Coverage.ps1
Normal file
@ -0,0 +1,91 @@
|
||||
# Evomedia.net Token Savers — https://github.com/evomedia-net/evo.zscripts
|
||||
# Created by Kelly Michels · dev@evomedia.net
|
||||
# Licensed under the MIT License. See LICENSE.
|
||||
|
||||
# Invoke-Coverage.ps1 — run the Pester suite with code coverage.
|
||||
#
|
||||
# .\tests\Invoke-Coverage.ps1 run everything, print the summary
|
||||
# .\tests\Invoke-Coverage.ps1 -Quiet just the numbers (for tooling)
|
||||
#
|
||||
# Writes coverage/ :
|
||||
# pester-coverage.xml JaCoCo, for anything that reads a standard format
|
||||
# coverage-summary.json the same shape vitest/jest emit, so the fleet
|
||||
# coverage collector reads all three identically
|
||||
#
|
||||
# WHY EVERY SCRIPT IS MEASURED, NOT JUST THE TESTED ONES
|
||||
# ------------------------------------------------------
|
||||
# CodeCoverage.Path covers every top-level *.ps1, including the ones no test
|
||||
# touches. They report 0% and drag the total down, which is correct: the
|
||||
# alternative measures only the files that already have tests and answers "how
|
||||
# well covered is the covered code" - a question nobody is asking. The same
|
||||
# mistake in vitest form made www look 91% covered when it was 17%.
|
||||
#
|
||||
# Pester counts *commands*, not statements. The collector labels it accordingly;
|
||||
# the two are not interchangeable and averaging them would be nonsense.
|
||||
|
||||
[CmdletBinding(PositionalBinding = $false)]
|
||||
param([switch]$Quiet)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$RepoRoot = Split-Path -Parent $PSScriptRoot
|
||||
$OutDir = Join-Path $RepoRoot "coverage"
|
||||
$Jacoco = Join-Path $OutDir "pester-coverage.xml"
|
||||
$Summary = Join-Path $OutDir "coverage-summary.json"
|
||||
|
||||
Import-Module Pester -MinimumVersion 5.0 -ErrorAction Stop
|
||||
|
||||
# Every script in the repo root. ZKiller/ZKillOnly and friends are included
|
||||
# deliberately - see the header.
|
||||
$targets = @(Get-ChildItem -Path $RepoRoot -Filter "*.ps1" -File | Select-Object -ExpandProperty FullName)
|
||||
if (-not $targets) { Write-Error "No *.ps1 found in $RepoRoot"; exit 1 }
|
||||
|
||||
if (Test-Path $OutDir) { Remove-Item $OutDir -Recurse -Force }
|
||||
New-Item -ItemType Directory -Force -Path $OutDir | Out-Null
|
||||
|
||||
$cfg = New-PesterConfiguration
|
||||
$cfg.Run.Path = Join-Path $RepoRoot "tests"
|
||||
$cfg.Run.PassThru = $true
|
||||
$cfg.Output.Verbosity = if ($Quiet) { "None" } else { "Normal" }
|
||||
$cfg.CodeCoverage.Enabled = $true
|
||||
$cfg.CodeCoverage.Path = $targets
|
||||
$cfg.CodeCoverage.OutputFormat = "JaCoCo"
|
||||
$cfg.CodeCoverage.OutputPath = $Jacoco
|
||||
$cfg.CodeCoverage.UseBreakpoints = $false # the profiler-based collector; far faster
|
||||
$cfg.Should.ErrorAction = "Continue"
|
||||
|
||||
$r = Invoke-Pester -Configuration $cfg
|
||||
|
||||
$analyzed = [int]$r.CodeCoverage.CommandsAnalyzedCount
|
||||
$executed = [int]$r.CodeCoverage.CommandsExecutedCount
|
||||
$pct = if ($analyzed -gt 0) { [math]::Round(($executed / $analyzed) * 100, 2) } else { 0 }
|
||||
|
||||
# Same shape as vitest/jest json-summary. "statements" is Pester's command
|
||||
# count; the key is reused so one reader handles every tool, and the unit is
|
||||
# named in the collector rather than pretended away here.
|
||||
$json = [ordered]@{
|
||||
total = [ordered]@{
|
||||
statements = [ordered]@{ pct = $pct; covered = $executed; total = $analyzed }
|
||||
}
|
||||
tests = [ordered]@{
|
||||
passed = [int]$r.PassedCount
|
||||
failed = [int]$r.FailedCount
|
||||
skipped = [int]$r.SkippedCount
|
||||
total = [int]$r.TotalCount
|
||||
}
|
||||
unit = "commands"
|
||||
} | ConvertTo-Json -Depth 6
|
||||
|
||||
# WriteAllText, not Set-Content: Set-Content -Encoding utf8 on 5.1 writes a BOM,
|
||||
# and a BOM makes python's json.load throw on the first character.
|
||||
[IO.File]::WriteAllText($Summary, $json, (New-Object Text.UTF8Encoding $false))
|
||||
|
||||
if (-not $Quiet) {
|
||||
Write-Host ""
|
||||
Write-Host "Coverage: $pct% ($executed/$analyzed commands across $($targets.Count) scripts)" -ForegroundColor Cyan
|
||||
Write-Host " $Jacoco"
|
||||
Write-Host " $Summary"
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
exit $(if ($r.FailedCount -gt 0) { 1 } else { 0 })
|
||||
Loading…
Reference in New Issue
Block a user