Swift.org 于 2026 年 9 月 15 日发布 Swift 6.4,并确认可以在 Swift Testing 测试中安全使用 XCTAssert,也可以在 XCTest 中使用 #expect。Swift 6.4 发布说明 这不代表两套框架的所有行为都能互换:遇到 Swift 6.4 XCTest 互操作报错,先找出哪套测试调用了另一套框架的断言,再核对工具链和 Package 的 swift-tools-version,不要一开始就重写旧测试。
适合正在把旧 XCTest 课程项目与新 Swift Testing 测试放在一起运行的学生。
如果你刚升级 Swift 工具链或 Package,可以按文中的条件判断是否需要调整互操作模式。
如果 Xcode 的测试报告与预期不一致,也可以用下面的步骤区分代码、配置与测试未运行。
Swift 6.4 XCTest 互操作报错:先按报告症状分流
先确认异常属于哪一种:测试显示通过,但断言似乎没有让它失败;测试仍在运行,却出现警告或现代化提示;或者测试直接失败、崩溃,甚至没有运行。它们不是同一种问题,看到警告也不等于测试逻辑已经通过。
Swift 6.4 支持在同一个测试源文件里放置 XCTest 和 Swift Testing 测试;Apple 也说明,文件包含两类测试时可以同时导入 XCTest 和 Testing。不过,“同一个文件里有两类测试”,不等于同一个测试函数可以随意混用两套 API。先定位具体的测试声明与调用,再判断是否发生了跨框架调用。Apple 的 XCTest 与 Swift Testing 迁移说明
Swift 6.4 里 XCTest 和 Swift Testing 能写在同一个测试文件吗?
可以在一个源文件中放置两套框架各自声明的测试。不过,如果某个测试函数通过辅助函数间接调用另一套框架的断言,那是跨框架互操作问题,应该继续检查互操作模式,不能仅凭“可以同文件”推断断言行为完全一致。
测试通过,但断言看起来没有生效
先搜索出问题的测试及其调用的辅助函数。如果 Swift Testing 的 @Test 调用了一个封装 XCTAssertEqual 的旧辅助函数,问题可能不在比较表达式本身,而在 XCTest 断言产生的跨框架问题如何被报告。Apple 的示例指出,在 none 模式下,这类 XCTest 断言失败可能没有测试失败消息;启用相应互操作后,它才会按模式显示为警告或失败。
反过来也要检查:XCTest 测试或它调用的辅助函数中是否用了 Swift Testing 的 Issue.record、#expect 等 API。不要只在测试函数正文里搜;旧项目常把断言藏在多个课程辅助函数中。
Swift Testing 里的 XCTAssert 失败,却没有显示错误怎么办?
沿调用链确认这条断言是否确实由 Swift Testing 测试触发,然后检查当前互操作模式。若模式为 none,跨框架问题会被忽略;不要先把辅助函数全部改写,先用最小复现确认切换模式后,报告是否按预期变化。
⚠️ 测试结果显示“通过”,只说明当前执行路径没有报告失败;它本身不能证明辅助函数里的断言已按预期传递到测试运行器。
核对版本条件,再解释警告或失败级别
互操作模式可以理解为课程的“批改规则”:它决定跨框架问题是被忽略、显示为警告,还是按失败处理。工具链是当前运行的 Swift 工具版本;swift-tools-version 则写在 Package.swift 开头,声明这个 Package 所需的 Swift 工具版本与清单兼容版本。它们彼此有关,但不是同一个设置。Swift Package Manager 对 swift-tools-version 的说明
先记录实际使用的工具链,再打开 Package.swift 查看 // swift-tools-version: 声明;如果是 Xcode 项目,也记录实际测试目标和运行报告。Apple 给出的默认规则如下。
| 互操作模式 | 跨框架问题如何呈现 | 排查时怎么理解 |
|---|---|---|
none |
不报告跨框架问题 | 断言看起来“没生效”时,先确认是否处于此模式 |
limited |
Swift Testing 问题保留原严重级别;XCTest 问题以警告和现代化提示报告 | 警告不是“完全没问题”,也不等同于测试失败 |
complete |
跨框架问题保留原严重级别;XCTest 问题附带现代化提示 | 适合确认旧 XCTest 断言是否真的失败 |
strict |
XCTest API 在 Swift Testing 测试中的使用会触发 fatalError |
检查阶段不要为了消除提示而盲目启用 |
默认模式会受工具链版本与 Package 的 swift-tools-version 影响:工具链低于 6.4 时默认是 none;工具链达到 6.4 或更高、但 Package 声明低于 6.4 时默认是 limited;两者都达到 6.4 或更高时默认是 complete。这些条件应分别记录,再与 Apple 的互操作模式与默认条件说明核对。
升级 Swift 6.4 后,怎么检查 XCTest 互操作模式?
先查看运行测试的工具链版本,再查看 Package 清单中的 swift-tools-version。对于通过 Swift Package Manager 启动的测试,可以在运行环境中设置 SWIFT_TESTING_XCTEST_INTEROP_MODE,其值为 none、limited、complete 或 strict;该变量用于覆盖模式。Swift Evolution 的互操作提案 ST-0021也记录了这一环境变量及各模式的行为。
如果测试由 Xcode 项目启动,不要因为变量名称已确认,就假设它已经传入了当前测试进程;先保留实际运行方式和报告。不要只为消除提示而随意改项目设置,先确认问题确实来自跨框架断言。
用决策条件选择下一步,不要先批量改断言
按检查结果走分支,修改时一次只改变一个条件:
- 若 Swift Testing 测试调用了封装 XCTest 断言的辅助函数,则先确认当前模式与报告内容;若错误级别与模式定义相符,先用最小测试复验,不要立刻改写整个辅助库。
- 若工具链与
swift-tools-version落在不同默认条件中,则先记录二者,再用相同测试比较默认模式与明确指定的模式;若结果未变,回头检查调用路径。 - 若 XCTest 测试或它的辅助函数调用了
#expect,则确认该调用是否被运行,以及报告是否记录跨框架问题;不要把测试目标未运行当成断言互操作失败。 - 若测试报告中出现现代化提示,但已知失败用例仍明确失败,则记录提示和失败结果,先不要为了“清掉警告”一次性替换旧断言。
- 若构建失败、测试被跳过或目标没有执行,则先查构建日志、活动测试目标与报告;在确认测试实际启动之前,不要归因于互操作模式。
不同模式改变的是跨框架问题的报告方式,并不负责修复测试目标选择错误、构建失败或测试逻辑错误。尤其不要为了让红色失败消失就直接改成更宽松的模式:那可能只是降低了报告可见度,并没有证明断言正确。
XCTest 里使用 #expect 为什么会出现测试问题?
这属于相反方向的跨框架调用:XCTest 测试使用了 Swift Testing 的预期表达式。Swift 6.4 的互操作支持这种组合,但仍需检查当前模式、调用路径和测试报告;“得到警告”“按失败报告”与“发生构建错误”不是同一种结果。
测试没有运行或构建失败:转查目标与报告
如果某个测试没有出现在结果里,或者整个测试目标没启动,先别继续调整断言。核对实际运行的 scheme、测试计划和测试目标,再看报告中该测试是失败、被跳过,还是压根没有进入测试列表。Xcode 的官方说明建议通过测试报告和结果导航定位实际运行内容;命令行测试也可以生成包含会话结果与日志的 .xcresults 结果包。运行测试并解读结果
项目本身无法构建时,错误发生在测试断言被执行之前;测试被跳过时,也不能据此判断跨框架断言的结果。此时保存构建日志与测试报告,再检查是否运行了预期目标。XCTest 也用于 UI 测试与性能测试;如果问题只发生在 UI 测试流程,不要直接用一个 Swift Testing 单元测试的结果替代它。Xcode 测试说明
提醒:如果课程项目是 Swift Package,可先在同一 Package 中核对测试清单与运行结果;如果是 Xcode 工程,先确认 scheme 当前指向的测试目标。两种入口的日志和配置并不完全相同,不能只看一条断言的输出就推断另一入口也执行了相同测试。
用一组成功与失败用例复核修复
在改互操作设置或断言之前,先保留一个最小复现:一条已知应该通过的测试,以及一条在条件不满足时应该失败的测试。两条用例都经过同一个辅助函数时,更容易看出问题究竟是断言未报告、模式改变了问题级别,还是目标根本没有运行。
按下面的清单逐项记录,确认结果前不要同时改动多处:
- [ ] 写下工具链版本、Package 的
swift-tools-version和当前互操作模式。 - [ ] 标明测试使用
@Test还是继承自XCTestCase,并记录触发断言的辅助函数。 - [ ] 运行已知应通过的用例,确认它出现在测试报告中且结果符合预期。
- [ ] 运行已知应失败的用例,核对报告是失败、警告还是没有跨框架问题记录。
- [ ] 只更改一个条件,再运行同一组用例并保存两次报告。
- [ ] 若测试未执行、项目不能构建,或报告与官方模式定义不符,就停止改写断言,先检查目标、运行入口和日志。
修复有效的标准不是“提示变少”,而是已知应通过的用例通过、已知应失败的用例能按当前模式被正确报告,而且测试目标确实完成了运行。若切换模式后只有警告与失败图标变化,却没有检查过失败用例,就还不能判定修复完成。
没有可运行 Xcode 项目时,再处理 Mac 环境
工具链核对后,测试仍无法运行,下一步该做什么?
如果问题是学校电脑不允许安装工具、手边没有可运行 Xcode 项目的 Mac 环境,先确认课程要求、允许使用的设备和项目交付方式,再决定是否借用学校设备、自备 Mac,或短期使用远程 Mac。若只是学习 Swift Package 的基础测试,可先按项目实际支持的工具链验证;若课程要求 Xcode 工程或 Apple 平台测试,就不能仅凭其他环境能编译代码,推断验收流程也可替代。
当前设备方案可能受安装权限、课程设备排期或现有工具链版本限制;换成另一台电脑也可能带来环境不一致与重复排查成本。此时比较的是能否按课程要求打开项目、运行测试并查看报告,而不只是“能不能写 Swift”。需要临时 Mac 环境时,可以先浏览 RUVCLOUD 中文站的相关说明,再通过 RUVCLOUD 套餐页面核对当前可用方案与访问方式;如果测试要长期稳定运行,或必须连接特定实体设备,则先评估自购 Mac、学校设备或其他获准环境是否更合适。确认适用后,再查看 RUVCLOUD 方案入口。
最后更新于 2026 年 10 月 10 日。Swift 6.4 发布信息、互操作模式、默认条件及工具变量核实自本文所引 Swift.org、Apple Developer、Swift Package Manager 与 Swift Evolution 官方文档;后续工具链发布或官方迁移说明调整时,应按新文档重新核对。