Swift Testingによる エラーのテスト

2K Views

October 24, 24

スライド概要

YUMEMI.grow Mobile #17 - connpass
https://yumemi.connpass.com/event/331368/

YUMEMI.grow Mobile で Swift Testing の話をしました #yumemi_grow - usami-kの日記
https://usami-k.hatenablog.com/entry/2024/10/24/231046

profile-image

https://usami-k.github.io/

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

Swift Testing による エラーのテスト 宇佐見公輔 2024-10-24 株式会社ゆめみ

2.

自己紹介 • 宇佐見公輔 ‣ 株式会社ゆめみ iOS テックリード • 最近のアウトプット ‣ Swift Testing を活用する(Mobile Act OSAKA 14) ‣ XCTest から Swift Testing へ(関モバ A #5) ‣ 3 次元回転とクォータニオン(iOSDC Japan 2024) 1 / 28

3.

Swift Testing の技術同人誌 • Swift Testing の技術同人誌を制作中 • 11 月 2 日(土)からの技術書典 17 に出展予定 ‣(今回はオンラインのみの出展) 2 / 28

4.

Swift Testing とは

5.

Swift Testing とは Swift 用の単体テストフレームワーク • Swift 公式の GitHub リポジトリで公開されている ‣ https://github.com/swiftlang/swift-testing • Xcode 16 に統合された • XCTest との関係 ‣ 従来の XCTest に比べて、Swift の機能をより活用 ‣ XCTest と同じプロジェクトで混在可能 Swift Testing とは 4 / 28

6.

Swift Testing の構成要素 • テスト関数 ‣ @Test 属性 • 期待値の確認 ‣ #expect マクロ • テストスイート ‣ @Suite 属性 • トレイト ‣ TestTrait / SuiteTrait Swift Testing とは 5 / 28

7.

テスト関数

8.

テスト関数定義:XCTest import XCTest class FoodTruckTests: XCTestCase { func testEngineWorks() { // ... } } • XCTestCase のサブクラス内で定義する必要がある • メソッド名を test 始まりで命名する必要がある テスト関数 7 / 28

9.

テスト関数定義:Swift Testing import Testing struct FoodTruckTests { @Test func engineWorks() { // ... } } • テスト関数はどこで定義してもよい • メソッドに @Test 属性をつければテスト関数になる テスト関数 8 / 28

10.

期待値の確認

11.

期待値の確認 // XCTest func testEngineWorks() throws { XCTAssertNotNil(engine.parts.first) XCTAssertGreaterThan(engine.batteryLevel, 0) XCTAssertTrue(engine.isRunning) } // Swift Testing @Test func engineWorks() throws { try #require(engine.parts.first != nil) #expect(engine.batteryLevel > 0) #expect(engine.isRunning) } 期待値の確認 10 / 28

12.

Xcode 上の表示 #expect 期待値の確認 マクロはテスト失敗時の結果をきれいに表示する 11 / 28

13.

テストスイート

14.

テストスイート struct FoodTruckTests { @Test func engineWorks() { // ... } } • テスト関数を含む型が、自動的にテストスイートになる • 後述するトレイトを使う場合は @Suite 属性を指定する テストスイート 13 / 28

15.

Swift の機能の活用 final class FoodTruckTests { init() async throws { // ... } deinit { // ... } } • 専用の setUp の代わりに、通常の init が使える • actor や @MainActor なども使える テストスイート 14 / 28

16.

トレイト

17.

トレイト テスト関数やテストスイートの振る舞いを指定する @Suite(.timeLimit(.minutes(1))) struct FoodTruckTests { @Test func engineWorks() { // ... } } • テストスイートのタイムアウト時間を指定する例 • ちなみに TimeLimitTrait.Duration は .minutes 指定のみ トレイト 16 / 28

18.

用意されているトレイト • .enabled / .disabled • .timeLimit • .serialized • .tags • .bug • .isRecursive トレイト 17 / 28

19.

Swift Testing の機能

20.

Swift Testing の機能 Swift Testing ならではの機能 • エラーのテスト • パラメトライズテスト • テストの並列実行 今回は、エラーのテストについて紹介 Swift Testing の機能 19 / 28

21.

エラーのテスト

22.

エラーのテスト:XCTest • 素朴に do 〜 catch でテストを書いた場合 func testExample() throws { let myModel = MyModel() do { try myModel.doSomething() XCTFail("Expect to throw error") } catch { XCTAssertEqual(error as? MyError, .someError) } } エラーのテスト 21 / 28

23.

エラーのテスト:XCTest • XCTAssertThrowsError を使うとより安全に書ける func testExample2() throws { let myModel = MyModel() XCTAssertThrowsError( try myModel.doSomething() ) { error in XCTAssertEqual(error as? MyError, .someError) } } エラーのテスト 22 / 28

24.

エラーのテスト:Swift Testing • #expect マクロで書ける @Test func example() throws { let myModel = MyModel() #expect(throws: MyError.someError) { try myModel.doSomething() } } エラーのテスト 23 / 28

25.

エラーのテスト:Swift Testing • 特定の型のエラーであるかを確認 #expect(throws: MyError.self) { ... } • 特定のエラーインスタンスと一致するかを確認 ‣ この場合、エラー型が Equatable であることが必要 #expect(throws: MyError.someError) { ... } エラーのテスト 24 / 28

26.

エラーのテストのカスタマイズ • エラー判定をカスタマイズしたい場合 ‣ エラーが Equatable でない場合などに有益 @Test func example2() throws { let myModel = MyModel() #expect { try myModel.doSomething() } throws: { error in return error as? MyError == .someError } } エラーのテスト 25 / 28

27.

エラーが発生しないことのテスト • 単にコードをテスト関数の中に書けばよい @Test func example3() throws { let myModel = MyModel() try myModel.doSomething2() } • #expect(throws: Never.self) という書き方も可能 ‣ エラーが throw されても処理を続行したい場合 エラーのテスト 26 / 28

28.

まとめ

29.

まとめ • Swift Testing の構成要素 ‣ テスト関数、期待値の確認、テストスイート、トレイト • Swift Testing の機能として、エラーのテストを紹介 ‣ 型やインスタンスの一致を確認 ‣ 確認処理のカスタマイズ まとめ 28 / 28