在進行 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 等多種 API | 統一使用 #expect |
| 失敗訊息 | 不易看見值 | 自動顯示實際值 |
| 重複測試 | 手動撰寫 for 迴圈 | 預設支援參數化測試 |
| 平行執行 | 有限 | 預設平行執行 |
最讓我驚豔的是參數化測試。
需要只改變值、重複驗證相同邏輯時,以前得跑 for 迴圈或複製貼上函式。
在 Swift Testing 中,只要將引數列表傳給 @Test,就會自動逐一執行。
它也會精確指出失敗案例使用的是哪些值。
現在就能使用嗎?
可以。如果是新專案,我建議現在就導入。
在 Xcode 16 以上、Swift 6 的環境中,幾乎不需要特別設定。
不過有一點需要知道:Swift Testing 和 XCTest 可以在同一個專案中共存。
也就是說,不必一夜之間重寫所有既有的 XCTest 程式碼。
新撰寫的測試使用 Swift Testing,既有測試再慢慢移植即可。
有一點要注意的是 UI 測試。會自動操作畫面的 XCUITest 系列,目前仍屬於 XCTest 的範圍。
因此,短期內以 Swift Testing 處理單元測試、以 XCTest 處理 UI 測試,是比較務實的組合。
移植時值得知道的事項
以下分享幾個我在實際移植過程中覺得有用的技巧。
首先,使用 init 和 deinit 取代 setUp、tearDown。因為 Swift Testing 會為每個測試建立新的實例。
因此能大幅減少測試之間狀態意外混用的錯誤。
如果某個值一定要存在才能進入下一步,請使用 #require,而不是 #expect。
條件不符合時,#require 會立即停止測試。
標籤(Tag)功能也很實用,可以將相關測試分組,一次執行或篩選。
要確認錯誤是否正確拋出時,可以使用 #expect(throws:)。
總結
Swift Testing 已不是剛推出的實驗功能,而是 Apple 正積極推動的下一個標準。
不必立刻全部改掉,但從新的測試開始逐一使用,很快就會習慣它的便利。
如果你曾對 iOS 測試程式碼感到受限,今天不妨先將一個測試移植成 @Test。

