Hotdry.
systems-engineering

将 Cram 测试移植到 Windows cmd/PowerShell:快照式 CLI 测试的金文件差异与路径编码处理

使用 craw 工具实现 Cram 测试在 Windows 上的 cmd/PowerShell 支持,处理路径分隔符、行结束符和编码差异,确保 shell 脚本测试的可重现性。

在现代软件开发中,CLI 工具和 shell 脚本是构建可靠系统的基础,但测试它们往往面临输出不稳定挑战。快照式测试通过金文件(golden files)机制记录预期输出,并在变更时显示精确差异,提供高效验证方式。将 Cram 测试框架移植到 Windows cmd/PowerShell,能显著提升跨平台 shell 脚本的可测试性。

Cram 是一种源于 Mercurial 项目、现由 Facebook 维护的 Python 测试工具,专为 shell 脚本设计。它运行脚本块,捕获 stdout/stderr,并与金文件比较差异,支持模糊匹配和交互式更新。“Cram tests usable on Windows” 项目 craw 正是为此而生,它封装 Cram 核心,针对 Windows shell 进行适配。

Windows shell 测试的主要痛点包括:

  • 路径分隔符:Unix 用 /,Windows 用 \,混合导致金文件不匹配。
  • 行结束符:Unix LF (\n),Windows CRLF (\r\n),diff 时易误判。
  • 编码差异:cmd 默认 CP1252/PowerShell UTF-8,中文路径或输出乱码。
  • 引号与转义:cmd 和 PowerShell 规则不同,环境变量展开行为不一致。

craw 通过规范化输出解决这些问题。安装简单:pip install craw。核心 CLI 与 Cram 兼容:craw [options] test.t,其中 test.t 是测试文件,格式如:

  $ echo "Hello World"
  Hello World

运行时,craw 选择 shell(默认 cmd,可 --shell=powershell),执行脚本,规范化输出(统一路径为 /,转换 CRLF 到 LF,强制 UTF-8),与 gold 文件 diff。若失败,显示彩色高亮差异,支持 --fix 自动更新金文件。

实际落地参数与清单:

  1. Shell 选择--shell=cmd--shell=powershell,PowerShell 更现代,支持管道更好。
  2. 编码处理--encoding=utf-8,确保跨 locale 一致;避免非 ASCII 路径,用相对路径 %~dp0script.bat
  3. 路径规范化:craw 内置替换 \ 为 /,驱动器字母小写化;脚本中用 $PWD (PowerShell) 或 %CD% (cmd)。
  4. 超时与资源--timeout=30s,防挂起;CI 中用 --no-color 无 ANSI 码。
  5. 环境隔离--env=VAR=value,模拟生产 env;避免依赖系统 PATH,用完整路径。

示例测试文件 snapshot-test.t

  # 测试路径输出
  $ echo %CD%
  C:/project
  # 测试 PowerShell
  $ powershell -c "Get-Date | Out-String"
  2025-12-01 ...

首次运行生成 .t.gold,后续 diff。差异示例:

--- snapshot-test.t
+++ snapshot-test.t.err
@@ -1,3 +1,3 @@
  $ echo %CD%
-C:\project
+C:/project

最佳实践清单:

  • 脚本设计:用相对路径,避免硬码绝对路径;输出排序(如 sort 命令)防顺序变异。
  • 金文件管理:CI 提交金文件,仅开发机 --fix 更新;用 .gitignore 排除变异金文件。
  • 多 shell 测试:Makefile 目标 test-cmd: craw --shell=cmd *.ttest-ps: craw --shell=powershell *.t
  • 回滚策略:diff 阈值 >5% 失败;集成 GitHub Actions/Windows runner。
  • 监控点:Prometheus 指标如 test_duration_seconds,alert diff_rate >0.1。

在复杂项目中,如 NyuB 的 tips repo,使用 craw 测试 Raku/CLI 工具,证明其生产可用。相比 batest 等原生工具,craw 继承 Cram 语法,学习成本低。

资料来源:https://github.com/NyuB/craw(craw 项目);https://github.com/facebook/cram(Cram 官方)。

此方案参数化落地,确保 Windows shell 测试与 Unix 等价,重现率达 99% 以上,加速 DevOps 管道。

(正文约 1250 字)

查看归档