系统学习 学习路径总入口:先选领域,再建立模型,最后用故障演练验证

版本信息最后核对:2026-10-25

用 Pester 给脚本和模块写可重复的测试,覆盖成功、失败和边界路径

适用场景

脚本开始被多人使用、要接入 CI、或修改后需要确认没有回归时,就应该写测试。适合验证函数返回值、抛错条件、管道输入、模块导出边界,以及对外部命令的调用次数。

一次性排障脚本不需要完整测试;但任何会被计划任务、发布流水线或其他人复用的逻辑,都值得至少覆盖主路径和一个失败路径。

核心概念

5.1 与 7.x 差异

常用操作

# 1. 确认 Pester 版本;旧版 3.4 的断言语法不能直接套用
PS C:\> Get-Module -ListAvailable Pester | Select-Object Name, Version, Path
PS C:\> Install-Module Pester -Scope CurrentUser -MinimumVersion 5.0 -Force

# 2. 被测函数,保存为 Get-Widget.ps1
function Get-Widget {
    param([string] $Name)
    if (-not $Name) { throw 'Name required' }
    [pscustomobject]@{ Name = $Name; Id = 42 }
}

# 3. 测试文件 Get-Widget.Tests.ps1
BeforeAll { . $PSScriptRoot/Get-Widget.ps1 }
Describe 'Get-Widget' {
    It 'returns the requested name' { (Get-Widget -Name 'api').Name | Should -Be 'api' }
    It 'throws for an empty name' { { Get-Widget -Name '' } | Should -Throw }
}

# 4. 运行单文件并输出详细结果;CI 中让失败返回非零并收集覆盖率
PS C:\> Invoke-Pester -Path .\Get-Widget.Tests.ps1 -Output Detailed
PS C:\> Invoke-Pester -Path .\tests -CI -CodeCoverage .\Get-Widget.ps1

# 5. Mock 外部依赖,验证调用次数而不是真的发请求
Describe 'Remove-Widget' {
    BeforeAll { function Remove-Widget { param($Name) Invoke-RestMethod -Uri "https://api.example.test/widgets/$Name" -Method Delete } }
    It 'calls the API once' {
        Mock Invoke-RestMethod { @{ ok = $true } }
        Remove-Widget -Name 'api'
        Should -Invoke Invoke-RestMethod -Times 1 -Exactly
    }
}

易错点

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. Pester 5 里为什么不能在 Describe 外写 $fixture = Get-Content ... 然后直接在 It 里用?
  2. 怎样验证函数确实调用了一次外部 API,而不是真的发请求?
  3. 流水线里 Pester 失败但任务仍显示成功,最可能缺了什么?
答案
  1. Pester 5 先执行发现阶段再运行测试,容器外的赋值时机和运行阶段不共享,变量可能为空;准备逻辑应放进 BeforeAll。
  2. 用 Mock Invoke-RestMethod 替换实现,再用 Should -Invoke Invoke-RestMethod -Times 1 -Exactly 断言调用次数和参数。
  3. 缺少 -CI 或没有检查 Pester 结果对象;默认失败不保证进程返回非零退出码,要在入口显式设置。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令