cmux-testing

cmux-testing

热门

cmux 测试规则,涵盖 Swift Testing、测试目标编译、测试接线以及包/重构验证。在添加或修改测试、涉及包/重构代码,或决定 reload.sh 是否足以验证时使用。

2.5万Star
2116Fork
更新于 2026/7/31
SKILL.md
readonly只读
name
cmux-testing
description

cmux 测试规则,涵盖 Swift Testing、测试目标编译、测试接线以及包/重构验证。在添加或修改测试、涉及包/重构代码,或决定 reload.sh 是否足以验证时使用。

cmux 测试

回归测试提交策略

针对 bug 修复的回归测试以两个提交的形式提交,以便 CI 证明测试能捕获该 bug:

  1. 仅包含失败的测试,不包含修复。CI 变红。
  2. 包含修复。CI 变绿。

然后,GitHub PR 的 Commits 选项卡会显示,没有修复时测试确实失败。

测试接线

cmuxTests/ 中的测试文件必须通过匹配的 PBXFileReferencePBXSourcesBuildPhase 条目接入 cmux.xcodeproj/project.pbxproj。如果添加了 .swift 文件但没有这些条目,Xcode 会静默忽略它:xcodebuild test -only-testing:cmuxTests/<TestClass> 和机器人审查都会通过,并显示“Executed 0 tests”,因此缺失的接线与干净的红色/绿色回归测试无法区分,直到真实用户遇到该 bug。此问题在 https://github.com/manaflow-ai/cmux/issues/4529 中针对 https://github.com/manaflow-ai/cmux/pull/4536 暴露。

workflow-guard-tests CI 作业运行 ./scripts/lint-pbxproj-test-wiring.sh。通过 Xcode 添加文件(拖入 cmuxTests 目标)或手动编辑 pbxproj 条目,使用已接线的兄弟文件(如 cmuxTests/TabManagerUnitTests.swift)作为模板。

测试质量策略

  • 不编写仅验证源代码文本、方法签名、AST 片段或 grep 风格模式的测试。
  • 不编写读取已检入的元数据或项目文件(Resources/Info.plistproject.pbxproj.xcconfig、源文件)仅为了断言存在某个键、字符串、plist 条目或片段的测试。
  • 测试通过可执行路径(单元、集成、端到端、CLI)验证可观察的运行时行为,而非实现形态。
  • 对于元数据更改,验证构建的应用包或依赖该元数据的运行时行为。
  • 如果行为尚无法端到端执行,先添加一个小的运行时接缝或测试工具,然后通过它进行测试。
  • 如果没有有意义的行為或工件级测试可行,则跳过虚假的回归测试并说明原因。

测试框架

Swift Testing(Swift 6 / Xcode 16)是所有单元和集成测试的默认框架:import Testing@Test@Suite#expect(...)try #require(...)。不要编写新的 import XCTest 测试,除非是 UI 测试。

  • UI 测试继续使用 XCTest/XCUITest。 Swift Testing 没有 XCUIApplication 集成。cmuxUITests/ 下的文件保留 XCTestCase;不要迁移或桥接它们。
  • 新的测试目标从 Swift Testing 开始。 每个新包的 Tests/<Name>Tests/ 从第一次提交起就使用它;Xcode 16 从 import Testing 自动检测框架,无需 Package.swift 配置。
  • 参数化测试使用 @Test(arguments: [...]) 而不是重复的方法。
  • 并行化。 Swift Testing 默认并行运行测试,包括跨套件。需要排序或保护共享可变状态的套件使用 .serialized,而不是锁或睡眠。
  • 标签通过 @Test(.tags(.something)) 让 CI 和本地运行可以选择性过滤。
  • 仅当现有编辑已经涉及 XCTest 文件时,才就地迁移。映射见 references/swift-testing-migration.md

测试目标验证

reload.sh 仅构建 cmux scheme,因此绿色 reload 并不能说明 cmuxTests/cmuxUITests 是否仍能编译。移动或重命名的符号可能使应用继续构建,但破坏测试目标(真实案例:write(to:atomically:) 拼写错误和移除的 TabManager.CommandResult 仅在 tests 作业中暴露)。在推送包/重构更改之前,使用 -derivedDataPath /tmp/cmux-<tag> 构建 cmux-unit scheme(加上针对 cmuxApp/AppDelegate 变更的 GlobalISel 变通标志),或让 tests CI 作业把关。

详细参考