SuperAPI AI 工具集

swift-testing

测试与质量

查看项目

更新于 10-15 14:47

技能介绍

用途

Swift Testing 技能为开发者提供关于现代 Swift Testing 框架的专业指导,涵盖最佳实践、测试模式与具体实现。当开发者提到 Swift Testing、@Test、#expect、#require 等关键词,或需要编写、重构、迁移 Swift 测试时,可使用该技能获得针对性建议。

主要能力

该技能覆盖以下主题:

  • 现代 Swift Testing 框架的核心语法与用法,包括 @Test、#expect、#require、@Suite。
  • 测试替身(test doubles):按照 Martin Fowler 的分类法,涵盖 Dummy、Fake、Stub、Spy、SpyingStub、Mock。
  • Fixtures:测试数据的构造模式与放置位置。
  • 集成测试:模块交互的测试模式。
  • 快照测试:UI 回归测试与基于文本的快照测试。
  • 从 XCTest 迁移到 Swift Testing 的完整指南。
  • 异步测试模式、confirmation、超时与取消。
  • 参数化测试:高效测试多个输入。
  • 测试组织:suites、tags、traits、并行执行。

使用方式

该技能以“决策树”和“分诊优先手册”的方式组织内容,根据开发者当前需求引导到对应的参考文件:

  • 刚开始使用 Swift Testing:阅读 test-organization.md 与 async-testing.md。
  • 需要创建测试数据:阅读 fixtures.md 与 test-doubles.md。
  • 测试多个输入:阅读 parameterized-tests.md。
  • 测试模块交互:阅读 integration-testing.md。
  • 测试 UI 回归:阅读 snapshot-testing.md。
  • 测试数据结构或状态:阅读 dump-snapshot-testing.md。
  • 从 XCTest 迁移:阅读 migration-xctest.md。

常见错误对应处理:

  • “XCTAssertEqual is unavailable”或需要现代化测试:使用 migration-xctest.md。
  • 需要测试异步代码:使用 async-testing.md。
  • 测试缓慢或不稳定:检查 F.I.R.S.T. 原则,按 test-doubles.md 使用正确的 mock。
  • 需要确定性测试数据:使用 fixtures.md,采用固定日期。
  • 需要高效测试多个场景:使用 parameterized-tests.md。
  • 需要验证组件交互:使用 integration-testing.md。

核心原则与约定

该技能要求遵循以下规则:

  • 所有新测试使用 Swift Testing 框架(@Test、#expect、#require、@Suite),而非 XCTest。
  • 测试始终采用清晰的 Arrange-Act-Assert 结构。
  • 遵循 F.I.R.S.T. 原则:Fast(快速)、Isolated(隔离)、Repeatable(可重复)、Self-Validating(自验证)、Timely(及时)。
  • 使用符合 Martin Fowler 分类法的测试替身术语。
  • Fixtures 放在模型附近,使用 #if DEBUG 保护,而非放在测试 target 中。
  • 测试替身放在接口附近,使用 #if DEBUG 保护,而非放在测试 target 中。
  • 优先使用状态验证而非行为验证,测试更简单、更不易脆弱。
  • 使用 #expect 进行软断言(失败后继续),使用 #require 进行硬断言(失败后停止)。

核心语法示例

基本测试:

import Testing

@Test func basicTest() {
    #expect(1 + 1 == 2)
}

带描述的测试:

@Test("Adding items increases cart count")
func addItem() {
    let cart = Cart()
    cart.add(item)
    #expect(cart.count == 1)
}

异步测试:

@Test func asyncOperation() async throws {
    let result = try await service.fetch()
    #expect(result.isValid)
}

Arrange-Act-Assert 模式:

@Test func calculateTotal() {
    // Given
    let cart = ShoppingCart()
    cart.add(Item(price: 10))
    cart.add(Item(price: 20))

    // When
    let total = cart.calculateTotal()

    // Then
    #expect(total == 30)
}

断言:

  • #expect 为软断言,失败后测试继续执行。
  • #require 为硬断言,失败后停止测试执行。

错误测试:

@Test func throwsError() {
    #expect(throws: ValidationError.self) {
        try validate(invalidInput)
    }
}

@Test func throwsSpecificError() {
    #expect(throws: ValidationError.emptyField) {
        try validate("")
    }
}

测试替身参考

按照 Martin Fowler 的定义:

  • Dummy:填充参数,从不使用,无验证。
  • Fake:可工作的实现,带有捷径,状态验证。
  • Stub:提供预设答案,状态验证。
  • Spy:记录调用以供验证,状态验证。
  • SpyingStub:Stub 与 Spy 的组合(最常见),状态验证。
  • Mock:预编程期望,自我验证,行为验证。

注意:Swift 社区所称的“Mock”通常是 SpyingStub。

测试替身应放在接口附近,而非测试 target 中,并使用 #if DEBUG 保护。

Fixtures

Fixtures 应放在模型附近,使用 #if DEBUG 保护,并提供合理的默认值。

测试金字塔

  • UI 测试(E2E):5%,端到端流程。
  • 集成测试:15%,模块交互。
  • 单元测试:80%,单个组件。

适用场景

  • 编写新的 Swift 测试。
  • 将现有 XCTest 测试迁移到 Swift Testing。
  • 测试异步代码、参数化输入、模块交互、UI 回归。
  • 构造确定性测试数据与测试替身。
  • 排查测试缓慢或不稳定的问题。

限制

资料未提供该技能的安装方式、收费模式、支持平台或具体版本要求,这些信息暂未提供。