遷移到 Swift Testing 的安全路線:
先共存,再把 helper 與模式逐步搬過去
這支 session 的核心訊息很務實:不要一次重寫所有 XCTest。用 Xcode 27 的 test framework interoperability 讓兩套 framework 共存,先新增 Swift Testing 測試,再逐步處理 cross-framework issues。
一句話結論
Swift Testing 遷移不是「把 XCTest 全刪掉」的專案,而是先讓新測試享受 @Test、#expect、parallel execution、parameterized tests 與 exit tests,再用 interoperability 把舊 helper 與 issue-reporting API 慢慢拉到新的模型。
Xcode 27 預設支援 interoperability,讓你可以先共存,再選擇要把 cross-framework issues 當 warning、error 或 fatal error。
遷移策略:舊測試不用立刻動
影片建議先把既有 XCTests 留在原位,只有在你本來就要更新某些測試時,再小批次改寫。既有 test target 可以同時包含 XCTest 與 Swift Testing;新測試可以直接寫成 Swift Testing function,只是不能放進 XCTest class 裡。
這個策略降低兩種風險:第一,不為了遷移而改動穩定測試;第二,團隊可以先在新的或常改的測試上學習 Swift Testing 語法與診斷輸出。
Interop 是遷移的橋,不是長期藉口
很多專案都有測試 helper 包了 XCTFail 或 XCTest assertions。當 Swift Testing 測試呼叫這些 helper 時,就會產生 cross-framework issue。interoperability 的目的,是讓這些 issue 仍能被 Xcode 安全呈現,不會因為框架不同而消失。
同樣地,Swift Testing 的 #expect、#require、Issue.record、Test.cancel 等能力,也可以在支援範圍內服務 XCTest。這讓你可以先把 helper 改成 Swift Testing API,同時不破壞舊 XCTest 的失敗語意。
四種 interoperability modes
limited 會把來自 XCTest 的 cross-framework issue 當 warning,舊 test plan 可能沿用這個模式;complete 會保留 error,較不容易漏掉問題;strict 對 XCTest API 產生的 cross-framework issue 直接 fatal,適合主動掃出要改的地方;none 則關掉 interoperability,不建議長期使用。
Swift Package 若要使用 complete mode,影片提到需要更新到 swift-tools-version: 6.4 或更新;也可以用環境變數 SWIFT_TESTING_XCTEST_INTEROP_MODE 覆寫模式。
常見遷移對照
XCTest assertion -> #expect / #require XCTFail -> Issue.record XCTSkip -> Test.cancel 或 .enabled / .disabled trait continueAfterFailure -> #require 控制哪個 expectation 需要 halt loop-generated cases -> @Test(arguments:) parameterized tests preconditionFailure -> #expect(processExitsWith:) exit tests
這些不是一比一語法替換而已。Swift Testing 的 traits 可以把 enablement logic 從 test body 移到宣告層;#require 讓你針對特定 expectation 決定是否中止,而不是把整個 XCTestCase 的 continue-after-failure 行為設成同一種。
遷移後的真正收益:參數化與 exit tests
parameterized tests 把巢狀 loop 產生的測試組合變成個別 test cases,並且預設可以平行執行。失敗時,Test navigator 能直接展開並過濾出是哪個參數組合失敗,不必用 debugger 或自行捕捉錯誤。
exit tests 則用 child process 執行可能 crash 或呼叫 preconditionFailure 的程式碼,再用 exit status 判斷測試結果。這對補齊 coverage 很實用,但影片也提醒 exit tests 支援平台包含 macOS、Linux、FreeBSD 與 Windows。
我會採用的遷移順序
- →不要大爆炸式重寫 XCTest;先讓兩套 framework 在同一 target 共存。
- →interoperability 讓跨框架 issue 不會消失,並可用 mode 管控嚴格度。
- →complete mode 比 limited 更適合防漏;strict 可用來找出必須改掉的 XCTest API。
- →遷移後重點不是語法更短,而是並行參數化測試、清楚 failure case 與 crash path coverage。