news 2026/9/8 20:34:32

PowerShell 仓库 Pester 测试指南:运行、编写与维护跨平台用例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PowerShell 仓库 Pester 测试指南:运行、编写与维护跨平台用例

PowerShell 仓库 Pester 测试指南:运行、编写与维护跨平台用例

【免费下载链接】PowerShellPowerShell for every system!项目地址: https://gitcode.com/GitHub_Trending/po/PowerShell

本指南以仓库 test/powershell/README.md 为骨架,系统讲解 PowerShell 仓库中 Pester 测试的执行方式、子进程启动规范、跨平台跳过策略与 Pending 约定。读者完成阅读后将掌握:用Start-PSPester运行与筛选整套 CI 测试、在用例内安全启动开发版pwsh子进程、用-Skip/-Pending正确表达"平台不适用"与"应当通过但暂未通过"两类状态,并把新用例放置到正确的测试目录。

PowerShell 仓库的 Pester 测试规模庞大(从引擎、语言解析器到各内置模块均有覆盖),这些用例同时运行于 Windows、Linux 与 macOS 的 CI 之上,因此对可移植性、进程隔离与状态表达有一套严格的约定。理解 Writing Pester Tests(由本 README 显式交叉引用)能进一步补齐编写侧的规范。

运行 Pester 测试:Start-PSPester 入口

仓库约定:先自行构建一份自托管(self-hosted)PowerShell,然后在仓库根目录、于该自托管 PowerShell 会话中执行Start-PSPester

Import-Module ./build.psm1 Start-PSPester

Start-PSPester定义在 build.psm1,其默认行为是:启动刚构建好的pwsh进程,导入 Pester 模块,并对默认路径test/powershell下的用例执行Invoke-Pester,最终以 NUnit XML 格式写出结果文件(默认pester-tests.xml)。关键默认参数如下:

参数默认值说明
Path(位置 0)test/powershell一个或多个测试文件/目录路径
TagCI,Feature只运行带这些标签的用例
ExcludeTagSlow排除的标签(会按提权状态自动追加)
OutputFormatNUnitXmlPester 输出格式,供 CI 消费
OutputFilepester-tests.xmlXML 结果文件路径

Start-PSPesterPath参数还内置了针对*.tests.ps1的 Tab 补全(见 build.psm1 的ArgumentCompleter),可以快速从命令行定位目标测试文件。

限定运行范围

仓库文档中给出了两种限定方式:

  • test/powershell/README.md 记载的写法是按名称模式过滤:Start-PSPester -Tests SomeTestSuite*
  • 根目录测试文档与当前 build.psm1 实现统一使用Path(位置 0)参数指定目录或文件,例如 testing-guidelines.md 中的示例:
# 运行某个目录下的所有用例 Start-PSPester -Path test/powershell/engine/Api # 或只运行某一个测试文件 Start-PSPester -Path test/powershell/engine/Api/XmlAdapter.Tests.ps1

在较新实现中优先采用-Path写法;-Path既接受目录,也接受具体.tests.ps1文件。

运行器在幕后做了什么

从 build.psm1 的实现可以看到,Start-PSPester会构造一条完整的启动命令并交给刚构建好的pwsh去执行,其中包括几项对测试正确性至关重要的动作:

  • 设置遥测退出:以$env:POWERSHELL_TELEMETRY_OPTOUT = 'yes'启动,避免测试受外部网络遥测行为干扰;
  • 注入测试模块路径:把临时测试模块目录前置到子进程的PSModulePath,使测试用模块可被自动加载;
  • Windows 下调低执行策略Set-ExecutionPolicy -Scope Process Unrestricted,规避默认Restricted策略对测试脚本的拦截;
  • 按提权状态动态调整标签:非管理员 Windows 会话自动追加排除RequireAdminOnWindows,Unix 非 sudo 会话自动追加排除RequireSudoOnUnix(见 build.psm1);
  • 始终携带-noprofile启动(build.psm1),这正是下面一节要展开的规范。

在用例内启动新的 pwsh 子进程:-noprofile 与开发版定位

许多集成类测试需要再启动一个全新的powershell进程来验证命令行行为。此时必须遵守两条铁律:

  1. 必须带-noprofile:用户的、系统的、被改动过的 profile 一旦被加载,会污染测试环境,导致用例在不该失败时失败。这正是上一节Start-PSPester自己也坚持用-noprofile启动子进程的原因——同一约定贯穿"运行器"与"用例"两个层面;
  2. 必须调用开发版 PowerShell,而非 PATH 中的第一个:本机很可能同时装有正式发布版pwsh,直接写pwsh会执行到错误解释器。正确做法是基于当前会话的$PsHome拼接出可执行文件路径——正在运行的正是开发版,从它的目录派生子进程就能保证测试的是当前构建。

README 给出的标准范例:

$powershell = Join-Path -Path $PsHome -ChildPath "pwsh" & $powershell -noprofile -command "ExampleCommand" | Should Be "ExampleOutput"

注意 Windows 上实际的可执行文件名是pwsh.exe,而统一写成pwsh在两侧均可解析(Unix 无扩展名、Windows 上按扩展名自动补全);若你所在分支要求更严格的写法,可显式区分平台。

这一模式在真实用例中大量落地,例如 test/powershell/Host/Base-Directory.Tests.ps1:

& $powershell -noprofile -c `$PROFILE | Should -Be $expectedProfile & $powershell -noprofile -c `$env:PSModulePath & $powershell -noprofile { (Get-PSReadLineOption).HistorySavePath } | Should -Be $expectedReadline & $powershell -noprofile { exit }

这些用例通过-noprofile干净地探测子进程在"零 profile 影响"下的$PROFILEPSModulePath、PSReadLine 配置与退出行为——任何一条规则被破坏(例如落到系统已装版本的 pwsh),断言都会失真。此外,根目录测试文档 testing-guidelines.md 也提示:即便只是在本机运行测试,也应确保外层 PowerShell 以-noprofile启动,因为非默认环境可能导致部分用例失败。

可移植性:用 -Skip 表达"平台专属"

仓库测试需要跑在 Windows、Linux、macOS 三种平台上,因此存在大量"仅在某个平台有效"的用例。约定是:不要删除或改写它们,而是通过 Pester 的-Skip参数配合跨平台自动变量$IsWindows$IsLinux$IsMacOS在运行时决定是否执行。

仅在 Windows 上运行的写法:

It "Should do something on Windows" -Skip:($IsLinux -Or $IsMacOS) { ... }

仅在 Linux / macOS 上运行的写法:

It "Should do something on Linux" -Skip:$IsWindows { ... }

真实仓库中有大量同款实践。例如 Windows 专属的执行策略用例 test/powershell/Modules/Microsoft.PowerShell.Security/ExecutionPolicy.Tests.ps1:

It "Should return Microsoft.Powershell.ExecutionPolicy PSObject on Windows" -Skip:($IsLinux -Or $IsMacOS) { ... } It "Should succeed on Windows" -Skip:($IsLinux -Or $IsMacOS) { ... }

文件系统层面的跨平台差异也会用同一手法处理,如 test/powershell/Modules/Microsoft.PowerShell.Management/Add-Content.Tests.ps1 中对不支持某 Provider 的平台显式跳过。

整块跳过:$PSDefaultParameterValues 技巧

当某个Describe内的用例"整块不适用于某平台"时,逐个加-Skip会显得啰嗦。WritingPesterTests.md 提供了基于$PSDefaultParameterValues的批量跳过方案:在BeforeAll中条件性地把It:skip置为$true,并在AfterAll中恢复原始值,从而使整个Describe(含其下所有Context/It)在非目标平台上报告为 Skipped 而非 Failed。这与逐条-Skip的语义一致,但更易维护。

与标签机制的分工

除了-Skip,仓库还通过Pester 标签管理"需要特殊权限"的用例(详见 WritingPesterTests.md 的 "Admin privileges in tests"):

  • 需要 Windows 管理员权限的用例标记为RequireAdminOnWindows
  • 需要 Unix 下sudo的用例标记为RequireSudoOnUnix(该标签优先于CI/Feature等其他标签)。

CI 会分两轮执行:常规轮次排除这些用例,专用轮次只运行它们。Start-PSPester在 build.psm1 中按当前会话是否提权自动向ExcludeTag追加对应标签,使"未提权的本地运行"与 CI 表现一致,也避免无权用例直接红掉。

Pending:标记"应当通过却暂未通过"的用例

-Skip(平台不适用、不应运行)不同,仓库还约定了一种状态表达:测试本身写得没问题、理应通过,但因为某个未解决的缺陷暂时失败。此时既不能删除用例,也不要用-Skip悄悄跳过,而应使用 Pending:

It "Should Pass" -Pending

Pending 会在结果报告中以独立状态呈现,时刻提醒维护者该用例背后还有未关闭的缺陷;同时按 README 的约定,应当就阻塞原因在项目问题跟踪中登记一条 issue,保证"有人负责、可追踪"。

真实仓库中能看到两种 Pending 形态:

  • 静态-Pending:例如 test/powershell/Host/Base-Directory.Tests.ps1 的It "Can start in directory where name contains wildcard characters" -Pending
  • 条件式与Set-ItResult:例如 test/powershell/Host/ConsoleHost.Tests.ps1 中使用Set-ItResult -Pending -Because "..."在用例体内根据运行时事实动态置为 Pending,以及-Pending:($IsWindows)(ConsoleHost.Tests.ps1)把条件化的 Pending 与平台判断结合。

编写用例的基本规范速览

README 所链接的 WritingPesterTests.md 是仓库内编写用例的权威细则,以下是与本主题强相关的要点,供对照自查:

  • 文件命名<描述性名称>.tests.ps1,例如XmlAdapter.Tests.ps1
  • Describe 必须打标签Describe需在CIFeatureScenario三选一,未打标签会被构建过程直接判失败。CI(单元级、秒级完成)、Feature(定期跑的功能级)、Scenario(不定期跑的跨功能集成级)三者层层放大范围;
  • 断言风格:基础值断言用Should -Be,类型检查用Should -BeOfType System.Int32;预期报错用Should -Throw -ErrorId(比消息更稳,不随文化/语言变化),需要深入检查 ErrorRecord 成员时配合-PassThru取回错误对象;
  • 作用域结构Describe内定义的MockTestDrive:内容随块退出而清理,Context是更细的分组层级,BeforeAll/BeforeEach/AfterEach/AfterAll用于搭建与拆除,避免在Describe中散落"自由代码"(其执行时机极易被误解);
  • 文件隔离:涉及文件操作时一律使用 Pester 内置的TestDrive:(即$TestDrive),测试结束后由 Pester 自动清空,避免对仓库与用户目录产生副作用;
  • 测试驱动数据:多组输入输出用It ... -TestCases $testCases驱动,配合描述性用例名;
  • 跨平台纪律:避免依赖注册表与 COM,避免断言平台间天然变化的资源计数(如加载的格式化文件数量),多行字符串比较需先规范化行尾(Windows 为\r\n,Unix 为\n,且受 clone 的 git 配置影响)。

测试目录布局:新用例放对位置

按 testing-guidelines.md 的"功能化布局"约定,Pester 测试统一位于 test/powershell 下:

  • engine:引擎级测试,其下细分为 Api、Basic、ETS(扩展类型系统)、Help、Logging、Module、ParameterBinding、Remoting 等子目录;
  • Host:控制台宿主相关(含 TabCompletion、Base-Directory、ConsoleHost 等用例,前述子进程启动示例正来自此处);
  • Language:语言与解析相关;
  • Modules:按内置模块组织(如Microsoft.PowerShell.SecurityMicrosoft.PowerShell.Management等),修某模块 cmdlet 时,用例应放进对应模块目录;
  • Provider、SDK、dsc 等:分别对应 Provider、托管 SDK 与 DSC 场景。

此外,构建/CI 运行器 build.psm1 还支持通过-IncludeFailingTest-IncludeCommonTests额外引入tools/failingTeststest/common下的用例,方便把"已知失败清单"与通用用例一并纳入本地验证。

小结

遵循上述约定即可获得"本地即 CI"的一致体验:用Start-PSPester(必要时以-Path收窄范围)跑整套或局部用例;在测试内部派生新pwsh时坚持从$PsHome定位开发版并强制-noprofile;用-Skip配合$IsWindows/$IsLinux/$IsMacOS表达平台差异,用RequireAdminOnWindows/RequireSudoOnUnix标签表达权限差异,用-Pending诚实记录尚未修复的缺陷并关联 issue;最后把新用例按功能放进 test/powershell 对应的子目录,并为每个Describe打上CI/Feature/Scenario标签。这套方法论既是仓库内部 CI 的根基,也是为 PowerShell 这类跨平台语言运行时贡献测试时最值得复用的工程范式。

【免费下载链接】PowerShellPowerShell for every system!项目地址: https://gitcode.com/GitHub_Trending/po/PowerShell

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 20:30:46

YOLO11工业级轴承缺陷检测方案:小目标高精度实时部署

简介&#xff1a;本资源是一套开箱即用的轴承外观缺陷智能检测系统&#xff0c;面向计算机、人工智能、自动化等专业学生、教师及工程技术人员&#xff0c;解决工业质检中凹槽、凹陷、擦伤、划痕四类常见缺陷的自动化识别问题。项目基于YOLO11深度学习框架构建&#xff0c;集成…

作者头像 李华
网站建设 2026/9/8 20:24:22

9款Claude Code插件实测:从上下文压缩到自动化编排,好用才留

这两年 Claude Code 的火爆程度&#xff0c;相信不用我多说了。命令行里跑 AI 编程助手&#xff0c;已经从“极客玩具”变成了不少人日常工作的标配。但项目火了&#xff0c;插件生态自然也跟着热闹起来&#xff0c;GitHub 上随便一搜就是一大堆号称“提效十倍”的插件&#xf…

作者头像 李华