修掉的:空 catch 5 处;名词白名单 7 处;default-value 开关、自带 -WhatIf、lab 的明文口令与 irm|iex 各挂抑制并写明理由。 MaxDepth:它是分析器拓出来的真 bug —— 参数声明了却从未使用,也就是配置里的 CatalogMaxDepth 是假的,前缀补全实际只查 1 层,而配置注释与 README 都承诺「向下找几层」。按确认过的原则处理:**先让文档不撒谎**,所以把整条链路去掉(配置默认值、三个函数的参数、70 处实参、配置注释),而不是留一个假旋钮。零行为变化。想真的支持多层补全时,那是一个独立决定。 剩下 3 条都是分析器的误判,而且我实测确认过其中一条:$sourcePath 被报「赋值后从未使用」,我照着改成 $null = 之后,Set-StrictMode -Version 3.0 下读未定义变量直接抛错,Security 套件的 BeforeAll 挂掉、4 条用例连带失败。恢复后才绿。 这一类误判有共同成因:静态分析看不到「在传给 Test-Case / It / Where-Object 的 scriptblock 里被使用」。所以我只对能证明是误判的挂抑制并写明理由,不为了数字好看去改代码。 验收:test.ps1 9/9 全绿(7 与 5.1)、100 个文件两版解析零错、Run-RealSmoke 4/4。
116 lines
3.6 KiB
PowerShell
116 lines
3.6 KiB
PowerShell
<#
|
||
.SYNOPSIS
|
||
BakNRet 测试用的极简断言运行器(零依赖,PS 5.1 / 7.x 通用)。
|
||
|
||
.DESCRIPTION
|
||
不用 Pester:本机只装了 3.4.0,缺少 `Should -Be` 这类 Pester 4+ 语法,
|
||
为跑几个测试去装 Pester 5 不划算。这里只需要 Test-Case + Assert-* 就够。
|
||
#>
|
||
|
||
$script:Passed = 0
|
||
$script:Failed = 0
|
||
$script:Failures = @()
|
||
|
||
function Reset-TestResult {
|
||
$script:Passed = 0
|
||
$script:Failed = 0
|
||
$script:Failures = @()
|
||
}
|
||
|
||
function Get-TestResult {
|
||
return [pscustomobject]@{
|
||
Passed = $script:Passed
|
||
Failed = $script:Failed
|
||
Failures = @($script:Failures)
|
||
}
|
||
}
|
||
|
||
function Test-Case {
|
||
param([string]$Name, [scriptblock]$Body)
|
||
|
||
try {
|
||
& $Body
|
||
$script:Passed++
|
||
Write-Host " [PASS] $Name" -ForegroundColor Green
|
||
}
|
||
catch {
|
||
$script:Failed++
|
||
$script:Failures += "$Name —— $($_.Exception.Message)"
|
||
Write-Host " [FAIL] $Name" -ForegroundColor Red
|
||
Write-Host " $($_.Exception.Message)" -ForegroundColor DarkGray
|
||
}
|
||
}
|
||
|
||
function Assert-Equal {
|
||
param($Expected, $Actual, [string]$Because)
|
||
if ($Expected -ne $Actual) {
|
||
throw ("期望 [{0}],实际 [{1}]{2}" -f $Expected, $Actual, $(if ($Because) { "($Because)" } else { '' }))
|
||
}
|
||
}
|
||
|
||
function Assert-True {
|
||
param($Condition, [string]$Because)
|
||
if (-not $Condition) { throw ("断言为真失败{0}" -f $(if ($Because) { ":$Because" } else { '' })) }
|
||
}
|
||
|
||
function Assert-False {
|
||
param($Condition, [string]$Because)
|
||
if ($Condition) { throw ("断言为假失败{0}" -f $(if ($Because) { ":$Because" } else { '' })) }
|
||
}
|
||
|
||
function Assert-Null {
|
||
param($Value, [string]$Because)
|
||
if ($null -ne $Value) {
|
||
throw ("期望为 null,实际 [{0}]{1}" -f $Value, $(if ($Because) { "($Because)" } else { '' }))
|
||
}
|
||
}
|
||
|
||
function Assert-FileExists {
|
||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '',
|
||
Justification = '误判:规则把结尾的 s 当复数,而这里的名词是 FileExists(Exists 不是复数)。')]
|
||
param([string]$Path, [string]$Because)
|
||
if (-not (Test-Path -LiteralPath $Path)) {
|
||
throw ("文件应当存在但不存在:{0}{1}" -f $Path, $(if ($Because) { "($Because)" } else { '' }))
|
||
}
|
||
}
|
||
|
||
function Assert-FileMissing {
|
||
param([string]$Path, [string]$Because)
|
||
if (Test-Path -LiteralPath $Path) {
|
||
throw ("文件不应存在但存在:{0}{1}" -f $Path, $(if ($Because) { "($Because)" } else { '' }))
|
||
}
|
||
}
|
||
|
||
function Assert-FileHashEqual {
|
||
param([string]$ExpectedPath, [string]$ActualPath)
|
||
Assert-FileExists $ExpectedPath
|
||
Assert-FileExists $ActualPath
|
||
$a = (Get-FileHash -LiteralPath $ExpectedPath -Algorithm SHA256).Hash
|
||
$b = (Get-FileHash -LiteralPath $ActualPath -Algorithm SHA256).Hash
|
||
if ($a -ne $b) { throw ("内容不一致:{0} vs {1}" -f $ExpectedPath, $ActualPath) }
|
||
}
|
||
|
||
function Write-TestSummary {
|
||
param([string]$Title = '测试')
|
||
|
||
Write-Host ""
|
||
Write-Host ("=" * 60)
|
||
if ($script:Failed -eq 0) {
|
||
Write-Host "$Title 全部通过:$($script:Passed) 项" -ForegroundColor Green
|
||
}
|
||
else {
|
||
Write-Host "$Title 通过 $($script:Passed) 项,失败 $($script:Failed) 项" -ForegroundColor Red
|
||
foreach ($failure in $script:Failures) { Write-Host " - $failure" -ForegroundColor Red }
|
||
}
|
||
Write-Host ("=" * 60)
|
||
|
||
return $script:Failed
|
||
}
|
||
|
||
Export-ModuleMember -Function @(
|
||
'Reset-TestResult', 'Get-TestResult', 'Test-Case',
|
||
'Assert-Equal', 'Assert-True', 'Assert-False', 'Assert-Null',
|
||
'Assert-FileExists', 'Assert-FileMissing', 'Assert-FileHashEqual',
|
||
'Write-TestSummary'
|
||
)
|