📸 SnapshotTesting

CI Slack

令人愉悦的 Swift 快照测试。

用法

一旦安装完成,无需额外配置。您可以导入 SnapshotTesting 模块并调用 assertSnapshot 函数。

import SnapshotTesting
import XCTest

class MyViewControllerTests: XCTestCase {
  func testMyViewController() {
    let vc = MyViewController()

    assertSnapshot(of: vc, as: .image)
  }
}

当断言首次运行时,快照会自动记录到磁盘,并且测试将失败,并打印出任何新记录的参考文件的文件路径。

❌ 失败 - 在磁盘上未找到参考。自动记录快照:…

打开 "…/MyAppTests/__Snapshots__/MyViewControllerTests/testMyViewController.png"

重新运行 “testMyViewController” 以针对新记录的快照进行测试。

重复测试运行将加载此参考并将其与运行时值进行比较。如果它们不匹配,测试将失败并描述差异。可以从 Xcode 的 Report Navigator 或通过检查失败的文件 URL 来检查失败情况。

您可以通过在断言中内联自定义快照,或使用 withSnapshotTesting 工具来记录新的参考。

// Record just this one snapshot
assertSnapshot(of: vc, as: .image, record: .all)

// Record all snapshots in a scope:
withSnapshotTesting(record: .all) {
  assertSnapshot(of: vc1, as: .image)
  assertSnapshot(of: vc2, as: .image)
  assertSnapshot(of: vc3, as: .image)
}

// Record all snapshots in an XCTestCase subclass:
class FeatureTests: XCTestCase {
  override func invokeTest() {
    withSnapshotTesting(record: .all) {
      super.invokeTest()
    }
  }
}

快照任何内容

虽然 Swift 社区中的大多数快照测试库都仅限于 UIViewUIImage,但 SnapshotTesting 可以处理 任何 Swift 平台上 任何 值的 任何 格式!

assertSnapshot 函数接受一个值和该值支持的任何快照策略。这意味着可以针对图像表示其属性和子视图层次结构的文本表示来测试视图或视图控制器。

assertSnapshot(of: vc, as: .image)
assertSnapshot(of: vc, as: .recursiveDescription)

视图测试是高度可配置的。您可以覆盖特征集合(针对特定尺寸类和内容尺寸类别)并生成设备无关的快照,所有这些都来自单个模拟器。

assertSnapshot(of: vc, as: .image(on: .iPhoneSe))
assertSnapshot(of: vc, as: .recursiveDescription(on: .iPhoneSe))

assertSnapshot(of: vc, as: .image(on: .iPhoneSe(.landscape)))
assertSnapshot(of: vc, as: .recursiveDescription(on: .iPhoneSe(.landscape)))

assertSnapshot(of: vc, as: .image(on: .iPhoneX))
assertSnapshot(of: vc, as: .recursiveDescription(on: .iPhoneX))

assertSnapshot(of: vc, as: .image(on: .iPadMini(.portrait)))
assertSnapshot(of: vc, as: .recursiveDescription(on: .iPadMini(.portrait)))

警告 快照必须使用最初拍摄参考的完全相同的模拟器进行比较,以避免图像之间的差异。

更好的是,SnapshotTesting 不仅限于视图和视图控制器!有许多可用的快照策略可供选择。

例如,您可以快照测试 URL 请求(例如,您的 API 客户端准备的那些)。

assertSnapshot(of: urlRequest, as: .raw)
// POST https://:8080/account
// Cookie: pf_session={"userId":"1"}
//
// email=blob%40pointfree.co&name=Blob

您可以快照测试 Encodable 值,以针对其 JSON 属性列表表示形式。

assertSnapshot(of: user, as: .json)
// {
//   "bio" : "Blobbed around the world.",
//   "id" : 1,
//   "name" : "Blobby"
// }

assertSnapshot(of: user, as: .plist)
// <?xml version="1.0" encoding="UTF-8"?>
// <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
//  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
// <plist version="1.0">
// <dict>
//   <key>bio</key>
//   <string>Blobbed around the world.</string>
//   <key>id</key>
//   <integer>1</integer>
//   <key>name</key>
//   <string>Blobby</string>
// </dict>
// </plist>

事实上,默认情况下,可以使用 任何 值的 mirror 对其进行快照测试!

assertSnapshot(of: user, as: .dump)
// ▿ User
//   - bio: "Blobbed around the world."
//   - id: 1
//   - name: "Blobby"

如果您的数据可以表示为图像、文本或数据,则可以为其编写快照测试!

文档

最新的文档可在此处获取

安装

Xcode

警告 默认情况下,Xcode 将尝试将 SnapshotTesting 包添加到您项目的主要应用程序/框架目标。请确保将 SnapshotTesting 添加到测试目标,如下一步所述。

  1. File 菜单中,导航到 Swift Packages 并选择 Add Package Dependency…
  2. 输入包仓库 URL:https://github.com/pointfreeco/swift-snapshot-testing
  3. 确认版本并让 Xcode 解析包。
  4. 在最终对话框中,将 SnapshotTesting 的 Add to Target 列更新为将包含快照测试的测试目标(如果您有多个测试目标,您可以稍后通过在其构建阶段手动链接库将 SnapshotTesting 添加到它们)。

Swift Package Manager

如果您想在任何其他使用 SwiftPM 的项目中使用 SnapshotTesting,请在 Package.swift 中将该包添加为依赖项

dependencies: [
  .package(
    url: "https://github.com/pointfreeco/swift-snapshot-testing",
    from: "1.12.0"
  ),
]

接下来,将 SnapshotTesting 添加为测试目标的依赖项

targets: [
  .target(name: "MyApp"),
  .testTarget(
    name: "MyAppTests",
    dependencies: [
      "MyApp",
      .product(name: "SnapshotTesting", package: "swift-snapshot-testing"),
    ]
  )
]

功能特性

插件

您是否编写了自己的 SnapshotTesting 插件?在此处添加它并提交 pull request!

相关工具

了解更多

SnapshotTesting 是使用面向见证的编程设计的。

这个概念(以及更多)在 Point-Free 的一系列剧集中进行了深入探讨,Point-Free 是一个探索函数式编程和 Swift 的视频系列,由 Brandon WilliamsStephen Celis 主持。

面向见证的编程和此库的设计在以下 Point-Free 剧集中进行了探讨

video poster image

许可证

此库在 MIT 许可证下发布。有关详细信息,请参阅 LICENSE