✅
Swift Testing Traitの使い方
概要
Swift 6.1 の Swift Testing
では、Trait を テストスイート(構造体)全体に適用できるようになりました。
本記事では「ログ出力を共通化する」というシンプルなケースで、TestScoping
を使った Trait の suite 適用を解説します。
やりたいこと
Swift 6.1で導入されたSuiteに Trait を適用して共通の前後処理をまとめます。
すべてのテスト関数の前後でログを出します
🟢 Start test...
(テスト処理)
🔴 End test...
Trait の定義
import Testing
struct LoggingTrait: SuiteTrait, TestScoping {
var isRecursive: Bool { false } // suite 全体に一度だけ適用される
func provideScope(
for test: Test,
testCase: Test.Case?,
performing function: @Sendable () async throws -> Void
) async throws {
print("🟢 Start suite: \(test.name)")
defer { print("🔴 End suite: \(test.name)") }
try await function()
}
}
extension Trait where Self == LoggingTrait {
static var logSuite: Self { Self() }
}
-
isRecursive = false
により、suite 全体で 1 回だけ実行されます。 -
provideScope
内でfunction()
を呼ぶ前後にログ出力。
テストコード(Suite に Trait を適用)
@Suite(.logSuite)
struct MyTests {
@Test
func testOne() throws {
print("✅ testOne executed")
}
@Test
func testTwo() throws {
print("✅ testTwo executed")
}
}
実行結果
🟢 Start suite: MyTests
✅ testOne executed
✅ testTwo executed
🔴 End suite: MyTests
Point
- Trait を suite に適用することで、全テスト共通の処理を一箇所にまとめられる
- 各テストがすっきりし、読みやすく・書きやすくなる
-
TestScoping
を使えば、開始前と終了後の処理を安全に挟み込める
isRecursive
の使い分け
値 | 適用範囲 | 向いている用途例 |
---|---|---|
false(非再帰) | suite全体で1回 | DB接続やモックの起動など重い処理 |
true(再帰) | 各テスト関数ごと | 毎テストで状態を初期化したいとき、ロギングなど軽量な処理 |
まとめ
機能 | 説明 |
---|---|
SuiteTrait |
テストスイート(構造体)に適用できる Trait |
TestScoping |
前後処理(スコープ)を追加するプロトコル |
provideScope(...) |
テスト実行を包み込むスコープ関数 |
応用編
下記のような用途にも利用が可能そうです
- DB接続の初期化&クリーンアップ
- サーバーのモック起動/停止
- テスト環境の一括セットアップ
Discussion