SuperAPI AI 工具集

snapshot-testing

测试与质量

查看项目

更新于 10-15 08:12

技能介绍

用途

该技能用于在 .NET 项目中引入基于 Verify 的快照测试(Snapshot Testing)。快照测试会捕获输出,并与人工审核过的基线进行比对:首次运行生成 .received. 文件(包含实际输出),开发者审核后批准生成 .verified. 文件,后续运行将输出与 .verified. 文件比对,检测到变化时测试失败,并通过 diff 工具展示差异供审核。这种方式既能捕获非预期变化,又允许通过显式批准放行有意变更。

适用场景包括:验证渲染输出(HTML 邮件、报告、生成代码);审批公共 API 表面以检测破坏性变更;测试 HTTP 响应体与响应头;校验序列化输出;捕获复杂对象中的非预期变化。

主要能力

  • 对象快照验证:直接对 DTO 等对象调用 Verify,生成可读的 .verified.txt。
  • 字符串/HTML 验证:通过 extension 参数指定扩展名(如 html),生成可在浏览器中查看的 .verified.html。
  • 邮件模板测试:渲染 MJML 等模板后快照,捕获 CSS/布局回归、模板变量损坏等问题。
  • API 表面审批:通过反射导出公共类型与成员,或使用 PublicApiGenerator 包生成完整 API 表面快照,任何变更都需显式批准。
  • HTTP 响应测试:将状态码、自定义响应头与响应体组合为一个匿名对象进行验证。
  • 动态值擦除(Scrub):使用 ScrubMember 或全局 VerifierSettings 擦除时间戳、GUID 等每次运行都变化的值,替换为占位符(如 Guid_1、DateTime_1)。
  • 文件组织与版本控制:推荐 Snapshots 目录结构,.gitignore 忽略 .received.,.gitattributes 将 .verified. 标记为 linguist-generated。
  • CI/CD 集成:在 CI 环境中禁用 diff 工具启动并改用 DiffPlex 输出,GitHub Actions 中设置 CI=true 并在失败时上传快照产物。

使用方式

安装包:

dotnet add package Verify.Xunit

或其他测试框架:

dotnet add package Verify.NUnit dotnet add package Verify.MSTest

配置 ModuleInitializer.cs:

using System.Runtime.CompilerServices;

public static class ModuleInitializer { [ModuleInitializer] public static void Init() { VerifyBase.UseProjectRelativeDirectory("Snapshots"); // DiffTools.UseOrder(DiffTool.Rider, DiffTool.VisualStudioCode); } }

基础用法示例:

[Fact] public Task VerifyUserDto() { var user = new UserDto( Id: "user-123", Name: "John Doe", Email: "john@example.com", CreatedAt: new DateTime(2025, 1, 15));

return Verify(user);

}

HTML 验证:

await Verify(html, extension: "html");

API 表面审批(使用 PublicApiGenerator):

dotnet add package PublicApiGenerator dotnet add package Verify.Xunit

[Fact] public Task ApproveApi() { var api = typeof(MyPublicClass).Assembly.GeneratePublicApi(); return Verify(api); }

动态值擦除:

return Verify(order) .ScrubMember("Id") .ScrubMember("CreatedAt");

全局擦除配置:

VerifierSettings.ScrubMembersWithType<DateTime>(); VerifierSettings.ScrubMembersWithType<DateTimeOffset>(); VerifierSettings.ScrubMembersWithType<Guid>(); VerifierSettings.AddScrubber(s => Regex.Replace(s, @"token=[a-zA-Z0-9]+", "token=SCRUBBED"));

CI 配置:

if (Environment.GetEnvironmentVariable("CI") == "true") { VerifyDiffPlex.UseDiffPlex(OutputType.Minimal); DiffRunner.Disabled = true; }

适用场景

  • 渲染 HTML/邮件:是,可捕获视觉回归。
  • API 表面:是,防止意外破坏。
  • 序列化输出:是,校验传输格式。
  • 复杂对象图:是,比手动断言更简单。
  • 简单值检查:否,应使用常规断言。
  • 业务逻辑:否,应使用显式断言。
  • 性能测试:否,应使用基准测试。

限制与注意事项

  • 不要对未擦除的随机/动态数据做快照,否则每次运行都会失败。
  • 不要提交 .received 文件,只提交 .verified 文件。
  • 不要用于简单断言(如计数),应使用 Assert.Equal。
  • 测试名称会成为文件名,应使用描述性命名。
  • 非文本内容需通过 extension 参数指定扩展名。

相关资源

  • Verify GitHub: https://github.com/VerifyTests/Verify
  • Verify.Xunit: https://github.com/VerifyTests/Verify.Xunit
  • ApiApprover: https://github.com/JakeGinnivan/ApiApprover
  • DiffPlex Integration: https://github.com/VerifyTests/Verify.DiffPlex