测试与代码质量

Swift Testing:取代 XCTest 的 Apple 新标准(快速总结)

在进行 iOS 开发、编写测试代码时,总会有开始觉得 XCTest 有些受限的时刻。

4 分钟阅读
Swift Testing:取代 XCTest 的 Apple 新标准(快速总结) 封面图

在进行 iOS 开发、编写测试代码时,总会有开始觉得 XCTest 有些受限的时刻。

我也有同感:以 func test 开头的函数名、XCTAssertEqual 这类冗长的断言,以及失败时无法一眼看出问题的消息。

就在这时,Apple 在 WWDC 2024 上发布了名为 Swift Testing 的新框架。

先说结论,Swift Testing 确实是 Apple 官方推出、用于取代 XCTest 的新标准。只需使用 @Test 宏和一个 #expect,就能编写简洁得多的测试,而且从 Xcode 16 起已内置。

本文将结合我的实际使用经验,整理 Swift Testing 是什么、与 XCTest 有何不同,以及现在是否可以立即使用。

什么是 Swift Testing?

Swift Testing 是 Apple 在 WWDC 2024 上公开的开源测试框架。

它充分利用了 Swift 的最新功能之一:宏。

最大的区别在于,XCTest 源自 Objective-C 时代,而 Swift Testing 从一开始就按照 Swift 的风格设计。

从 Xcode 16 起无需单独安装即可使用,Swift 软件包中也能直接使用。

最明显的变化是语法。测试函数名不再需要以 test 开头。

只需在函数上方添加 @Test,它就会成为一个测试。

import Testing

@Test func 检查_购物车_总价是否正确() {
    let cart = Cart(items: [1000, 2000])
    #expect(cart.total == 3000)  // 失败时显示实际值
}

如上面的代码所示,只需在 #expect 中直接放入普通的比较表达式即可,无需记住 XCTAssertEqual 和 XCTAssertTrue。


它与 XCTest 有什么不同?

我把亲自迁移代码时感受到的主要区别整理成了表格。(截至 2026 年)

项目 XCTest Swift Testing
测试声明 以 func test 开头 @Test 宏
断言 多个,如 XCTAssertEqual 统一使用 #expect
失败消息 不易看清值 自动显示实际值
重复测试 手动编写 for 循环 默认支持参数化测试
并行执行 有限 默认并行执行

最让我惊喜的是参数化测试。

需要只改变值、重复验证相同逻辑时,以前要运行 for 循环或复制粘贴函数。

在 Swift Testing 中,只需向 @Test 传入参数列表,它就会自动逐个执行。

它还会准确指出失败用例对应的值。

现在就可以使用吗?

可以。如果是新项目,我建议现在就采用。

在 Xcode 16 或更高版本、Swift 6 环境下,几乎不需要进行额外配置。

不过有一点需要了解:Swift Testing 和 XCTest 可以在同一个项目中共存。

也就是说,不必一夜之间重写所有现有的 XCTest 代码。

新编写的测试使用 Swift Testing,现有测试慢慢迁移即可。

从新测试开始逐个迁移就足够了
从新测试开始逐个迁移就足够了

需要注意的一点是 UI 测试。自动操作屏幕的 XCUITest 系列目前仍属于 XCTest 的范围。

因此,暂时采用单元测试使用 Swift Testing、UI 测试使用 XCTest 的组合更为实际。


迁移时值得了解的事项

下面介绍几个我在实际迁移过程中觉得有用的技巧。

首先,用 init 和 deinit 代替 setUp 和 tearDown。因为 Swift Testing 会为每个测试创建新实例。

这样可以大幅减少测试之间意外共享状态的问题。

当某个值必须存在才能进入下一步时,使用 #require,而不是 #expect。

如果条件不满足,#require 会立即停止测试。

看到绿灯后,@Test 会让人不知不觉上瘾
看到绿灯后,@Test 会让人不知不觉上瘾

标签(Tag)功能也很实用,可以将相关测试分组后一次运行或筛选。

要确认错误是否正确抛出,可以使用 #expect(throws:)。

总结

Swift Testing 已不再是刚出现的实验功能,而是 Apple 正在推动的下一个标准。

不必马上改变所有内容,但从新测试开始逐个使用,很快就会习惯它的便利。

如果你曾对 iOS 测试代码感到受限,今天不妨先把一个测试迁移到 @Test。

延伸阅读