<# .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 { 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' )