Upgrade to Pro — share decks privately, control downloads, hide ads and more …

モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テス...

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for Yu Sugawara Yu Sugawara
September 13, 2026

 モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用

Avatar for Yu Sugawara

Yu Sugawara

September 13, 2026

More Decks by Yu Sugawara

Other Decks in Programming

Transcript

  1. モバイルSuica 9:41 SuicaをiPhoneの中で管理 – iPhoneをタッチして乗車・ 支払い – 残高はiPhone内のICチップ に記録 –

    発行・チャージ・グリーン 券・定期券購入がアプリで 完結 出典: App Store「Suica」1 1. iPhoneは、米国および他の国々で登録されたApple Inc.の商標です。App StoreはApple Inc.のサービスマークです。 ↩︎ 10 Copyright © 2026 East Japan Railway Company. All rights reserved.
  2. 実機でしか確認できない機能例 今日の題材 IC NFCタグを 読み取る 対象: 外部のタグ Bluetooth機器と 通信する 対象:

    外部の機器 カメラで QRコードを読む 対象: 現実の被写体 ICチップへ アクセスする 対象: 端末内のICチップ ほかにも 位置情報、外部デバイス連携 など 16 Copyright © 2026 East Japan Railway Company. All rights reserved.
  3. チャージ時に何が起きているか チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 UI操作 UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 18 Copyright © 2026 East Japan Railway Company. All rights reserved.
  4. チャージ時に何が起きているか チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 UI操作 UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス ❶ チャージ結果と残高を画面に反映 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 19 Copyright © 2026 East Japan Railway Company. All rights reserved.
  5. チャージ時に何が起きているか チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 UI操作 UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 ❷ ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 20 Copyright © 2026 East Japan Railway Company. All rights reserved.
  6. チャージ時に何が起きているか チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 UI操作 UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 21 Copyright © 2026 East Japan Railway Company. All rights reserved.
  7. チャージ時に何が起きているか チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 UI操作 UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 22 Copyright © 2026 East Japan Railway Company. All rights reserved.
  8. チャージ時に何が起きているか チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 UI操作 UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 23 Copyright © 2026 East Japan Railway Company. All rights reserved.
  9. チャージ時に何が起きているか チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 UI操作 UI操作 APIサーバーへのアクセス ❻ ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 24 Copyright © 2026 East Japan Railway Company. All rights reserved.
  10. それぞれの動作確認観点 チャージ処理 テスト設計の論点 ❶ 金額・決済方法を選択 UIと状態更新の確認方法 ❷ チャージ確定ボタンを押下 処理の呼び出し確認方法 ③

    API通信 通信を差し替えるのか、実環境か ④ 3DS認証(必要な場合) 認証結果のみ確認か、フロー全体か ⑤ ICチップ書き込み 処理を差し替えるか、実機書き込みか ❻ チャージ成功 UIと状態更新の確認方法 UI操作 UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 25 Copyright © 2026 East Japan Railway Company. All rights reserved.
  11. それぞれの動作確認観点 チャージ処理 テスト設計の論点 ❶ 金額・決済方法を選択 UIと状態更新の確認方法 ❷ チャージ確定ボタンを押下 処理の呼び出し確認方法 ③

    API通信 通信を差し替えるのか、実環境か ④ 3DS認証(必要な場合) 認証結果のみ確認か、フロー全体か ⑤ ICチップ書き込み 処理を差し替えるか、実機書き込みか ❻ チャージ成功 UIと状態更新の確認方法 UI操作 UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 26 Copyright © 2026 East Japan Railway Company. All rights reserved.
  12. それぞれの動作確認観点 チャージ処理 テスト設計の論点 ❶ 金額・決済方法を選択 UIと状態更新の確認方法 ❷ チャージ確定ボタンを押下 処理の呼び出し確認方法 ③

    API通信 通信を差し替えるのか、実環境か ④ 3DS認証(必要な場合) 認証結果のみ確認か、フロー全体か ⑤ ICチップ書き込み 処理を差し替えるか、実機書き込みか ❻ チャージ成功 UIと状態更新の確認方法 UI操作 UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 27 Copyright © 2026 East Japan Railway Company. All rights reserved.
  13. それぞれの動作確認観点 チャージ処理 テスト設計の論点 ❶ 金額・決済方法を選択 UIと状態更新の確認方法 ❷ チャージ確定ボタンを押下 処理の呼び出し確認方法 ③

    API通信 通信を差し替えるのか、実環境か ④ 3DS認証(必要な場合) 認証結果のみ確認か、フロー全体か ⑤ ICチップ書き込み 処理を差し替えるか、実機書き込みか ❻ チャージ成功 UIと状態更新の確認方法 UI操作 UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 28 Copyright © 2026 East Japan Railway Company. All rights reserved.
  14. それぞれの動作確認観点 チャージ処理 テスト設計の論点 ❶ 金額・決済方法を選択 UIと状態更新の確認方法 ❷ チャージ確定ボタンを押下 処理の呼び出し確認方法 ③

    API通信 通信を差し替えるのか、実環境か ④ 3DS認証(必要な場合) 認証結果のみ確認か、フロー全体か ⑤ ICチップ書き込み 処理を差し替えるか、実機書き込みか ❻ チャージ成功 UIと状態更新の確認方法 UI操作 UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 29 Copyright © 2026 East Japan Railway Company. All rights reserved.
  15. それぞれの動作確認観点 チャージ処理 テスト設計の論点 ❶ 金額・決済方法を選択 UIと状態更新の確認方法 ❷ チャージ確定ボタンを押下 処理の呼び出し確認方法 ③

    API通信 通信を差し替えるのか、実環境か ④ 3DS認証(必要な場合) 認証結果のみ確認か、フロー全体か ⑤ ICチップ書き込み 処理を差し替えるか、実機書き込みか ❻ チャージ成功 UIと状態更新の確認方法 UI操作 UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 30 Copyright © 2026 East Japan Railway Company. All rights reserved.
  16. それぞれの動作確認観点 チャージ処理 テスト設計の論点 ❶ 金額・決済方法を選択 UIと状態更新の確認方法 ❷ チャージ確定ボタンを押下 処理の呼び出し確認方法 ③

    API通信 通信を差し替えるのか、実環境か ④ 3DS認証(必要な場合) 認証結果のみ確認か、フロー全体か ⑤ ICチップ書き込み 処理を差し替えるか、実機書き込みか ❻ チャージ成功 UIと状態更新の確認方法 UI操作 UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 31 Copyright © 2026 East Japan Railway Company. All rights reserved.
  17. 共通処理とOS固有の処理がある チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 共通 画面と選択状態 UI操作 チャージ処理を呼ぶ UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 OS固有 通信とデータ操作 呼び出しと分岐 認証画面の表示 呼び出しと判定 ICチップ書き込み 成功・失敗の判定 残高と結果の表示 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 32 Copyright © 2026 East Japan Railway Company. All rights reserved.
  18. 共通処理とOS固有の処理がある チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 共通 画面と選択状態 UI操作 チャージ処理を呼ぶ UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 OS固有 通信とデータ操作 呼び出しと分岐 認証画面の表示 呼び出しと判定 ICチップ書き込み 成功・失敗の判定 残高と結果の表示 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 33 Copyright © 2026 East Japan Railway Company. All rights reserved.
  19. 共通処理とOS固有の処理がある チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 共通 画面と選択状態 UI操作 チャージ処理を呼ぶ UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 OS固有 通信とデータ操作 呼び出しと分岐 認証画面の表示 呼び出しと判定 ICチップ書き込み 成功・失敗の判定 残高と結果の表示 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 34 Copyright © 2026 East Japan Railway Company. All rights reserved.
  20. 共通処理とOS固有の処理がある チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 共通 画面と選択状態 UI操作 チャージ処理を呼ぶ UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 OS固有 通信とデータ操作 呼び出しと分岐 認証画面の表示 呼び出しと判定 ICチップ書き込み 成功・失敗の判定 残高と結果の表示 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 35 Copyright © 2026 East Japan Railway Company. All rights reserved.
  21. 共通処理とOS固有の処理がある チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 共通 画面と選択状態 UI操作 チャージ処理を呼ぶ UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 OS固有 通信とデータ操作 呼び出しと分岐 認証画面の表示 呼び出しと判定 ICチップ書き込み 成功・失敗の判定 残高と結果の表示 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 36 Copyright © 2026 East Japan Railway Company. All rights reserved.
  22. 共通処理とOS固有の処理がある チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 共通 画面と選択状態 UI操作 チャージ処理を呼ぶ UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 OS固有 通信とデータ操作 呼び出しと分岐 認証画面の表示 呼び出しと判定 ICチップ書き込み 成功・失敗の判定 残高と結果の表示 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 37 Copyright © 2026 East Japan Railway Company. All rights reserved.
  23. 共通処理とOS固有の処理がある チャージ処理 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④ 3DS認証(必要な場合)

    ⑤ ICチップ書き込み ❻ チャージ成功 共通 画面と選択状態 UI操作 チャージ処理を呼ぶ UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 OS固有 通信とデータ操作 呼び出しと分岐 認証画面の表示 呼び出しと判定 ICチップ書き込み 成功・失敗の判定 残高と結果の表示 ※アプリ画面は説明用のイメージで、実際の開発画面とは異なります 38 Copyright © 2026 East Japan Railway Company. All rights reserved.
  24. 共通処理とOS固有処理の分け方 チャージ処理 40 ❶ 金額・決済方法を選択 ❷ チャージ確定ボタンを押下 ③ API通信 ④

    3DS認証(必要な場合) ⑤ ICチップ書き込み ❻ チャージ成功 共通 画面と選択状態 UI操作 チャージ処理を呼ぶ UI操作 APIサーバーへのアクセス ブラウザを利用した認証 ICチップへのアクセス チャージ結果と残高を画面に反映 OS固有 通信とデータ操作 呼び出しと分岐 認証画面の表示 呼び出しと判定 ICチップ書き込み 成功・失敗の判定 残高と結果の表示 Copyright © 2026 East Japan Railway Company. All rights reserved.
  25. 1 採用したアーキテクチャ 責務の分け方 それぞれの責務 UI Layer UI elements State holders

    Domain Layer UI Layer 表示する内容を組み立てて画面に描く 画面の状態を保持し、処理を呼び出す Domain Layer 画面にもデータの取得元にも依存しない アプリ固有の処理の流れを組み立てる Data Layer Repositories Data Sources Data Layer データの取得元を隠し、アプリの形へ変換する OS・端末・ネットワークに実際に触れる 1. Android アプリ アーキテクチャ ガイドを元に作成 ↩︎ 42 Copyright © 2026 East Japan Railway Company. All rights reserved.
  26. 1 採用したアーキテクチャ 責務の分け方 それぞれの責務 UI Layer UI elements State holders

    Domain Layer UI Layer 表示する内容を組み立てて画面に描く 画面の状態を保持し、処理を呼び出す Domain Layer 画面にもデータの取得元にも依存しない アプリ固有の処理の流れを組み立てる Data Layer Repositories Data Sources Data Layer データの取得元を隠し、アプリの形へ変換する OS・端末・ネットワークに実際に触れる 1. Android アプリ アーキテクチャ ガイドを元に作成 ↩︎ 43 Copyright © 2026 East Japan Railway Company. All rights reserved.
  27. 1 採用したアーキテクチャ 責務の分け方 それぞれの責務 UI Layer UI elements State holders

    Domain Layer UI Layer 表示する内容を組み立てて画面に描く 画面の状態を保持し、処理を呼び出す Domain Layer 画面にもデータの取得元にも依存しない アプリ固有の処理の流れを組み立てる Data Layer Repositories Data Sources Data Layer データの取得元を隠し、アプリの形へ変換する OS・端末・ネットワークに実際に触れる 1. Android アプリ アーキテクチャ ガイドを元に作成 ↩︎ 44 Copyright © 2026 East Japan Railway Company. All rights reserved.
  28. 1 採用したアーキテクチャ 責務の分け方 それぞれの責務 UI Layer UI elements State holders

    Domain Layer UI Layer 表示する内容を組み立てて画面に描く 画面の状態を保持し、処理を呼び出す Domain Layer 画面にもデータの取得元にも依存しない アプリ固有の処理の流れを組み立てる Data Layer Repositories Data Sources Data Layer データの取得元を隠し、アプリの形へ変換する OS・端末・ネットワークに実際に触れる 1. Android アプリ アーキテクチャ ガイドを元に作成 ↩︎ 45 Copyright © 2026 East Japan Railway Company. All rights reserved.
  29. チャージ画面のレイヤー構成 View UI Layer iOS / Android 金額・決済方法の選択、チャージ操作、結果の表示 画面を描画 StateHolder

    選択状態を保持し、ChargeUseCaseを呼び出す Domain Layer iOS / Android UseCase チャージ完了までの処理フローを制御する Repository Data Layer iOS / Android チャージや残高に関するデータ操作を提供する DataSource API通信などの具体的な入出力を行う ※資料用に編集しており、実際の構成を正確に表しているものではありません 46 Copyright © 2026 East Japan Railway Company. All rights reserved.
  30. UIはネイティブの表現を使用したい View UI Layer iOS / Android 金額・決済方法の選択、チャージ操作、結果の表示 StateHolder 画面を描画

    各OSの ネイティブ で表現 選択状態を保持し、ChargeUseCaseを呼び出す Domain Layer iOS / Android UseCase チャージ完了までの処理フローを制御する Repository Data Layer iOS / Android チャージや残高に関するデータ操作を提供する DataSource API通信などの具体的な入出力を行う ※資料用に編集しており、実際の構成を正確に表しているものではありません 47 Copyright © 2026 East Japan Railway Company. All rights reserved.
  31. 複雑な仕様を両OSで揃えたい View 金額・決済方法の選択、チャージ操作、結果の表示 UI Layer 画面を描画 StateHolder 選択状態を保持し、ChargeUseCaseを呼び出す Domain Layer

    UseCase チャージ完了までの処理フローを制御する Repository チャージや残高に関するデータ操作を提供する Data Layer iOS / Androidで 共通 DataSource API通信などの具体的な入出力を行う ※資料用に編集しており、実際の構成を正確に表しているものではありません 48 Copyright © 2026 East Japan Railway Company. All rights reserved.
  32. 処理を共通化 責務の分け方 実装の持ち方 UI Layer UI elements State holders iOS

    / Android それぞれ実装 Domain Layer Data Layer Repositories KMP(共通) Kotlinで1つ Data Sources 49 Copyright © 2026 East Japan Railway Company. All rights reserved.
  33. SwiftからKMPを使用する iOS Swift import / 呼び出し XCFramework KMP Kotlin UseCase

    Repository DataSource Objective-C互換API ビルド 自動生成されるヘッダー bridge Kotlin/Nativeバイナリ Kotlinランタイム UseCase、Repository、DataSource 51 Copyright © 2026 East Japan Railway Company. All rights reserved.
  34. SwiftからKMPを使用する iOS Swift import / 呼び出し XCFramework KMP Kotlin UseCase

    Repository DataSource Objective-C互換API ビルド 自動生成されるヘッダー bridge Kotlin/Nativeバイナリ Kotlinランタイム UseCase、Repository、DataSource 52 Copyright © 2026 East Japan Railway Company. All rights reserved.
  35. SwiftからKMPを使用する iOS Swift import / 呼び出し XCFramework KMP Kotlin UseCase

    Repository DataSource Objective-C互換API ビルド 自動生成されるヘッダー bridge Kotlin/Nativeバイナリ Kotlinランタイム UseCase、Repository、DataSource 53 Copyright © 2026 East Japan Railway Company. All rights reserved.
  36. 処理を共通化 View UI Layer iOS / Android 金額・決済方法の選択、チャージ操作、結果の表示 画面を描画 StateHolder

    選択状態を保持し、ChargeUseCaseを呼び出す Domain Layer KMP(共通) UseCase チャージ完了までの処理フローを制御する Repository Data Layer KMP(共通) チャージや残高に関するデータ操作を提供する DataSource API通信などの具体的な入出力を行う ※資料用に編集しており、実際の構成を正確に表しているものではありません 54 Copyright © 2026 East Japan Railway Company. All rights reserved.
  37. KMPは必須条件ではない View UI Layer iOS / Android 金額・決済方法の選択、チャージ操作、結果の表示 画面を描画 StateHolder

    選択状態を保持し、ChargeUseCaseを呼び出す Domain Layer iOS / Android UseCase チャージ完了までの処理フローを制御する Repository Data Layer iOS / Android チャージや残高に関するデータ操作を提供する Swiftで 実装して もよい DataSource API通信などの具体的な入出力を行う ※資料用に編集しており、実際の構成を正確に表しているものではありません 55 Copyright © 2026 East Japan Railway Company. All rights reserved.
  38. レイヤーで責務を分ける iOS KMP(共通) Android View / StateHolder View / StateHolder

    ChargeUseCase Repository DataSource ※資料用に編集しており、実際の構成を正確に表しているものではありません 56 Copyright © 2026 East Japan Railway Company. All rights reserved.
  39. 共通処理とOS固有処理をつなぐ iOS KMP(共通) Android View / StateHolder View / StateHolder

    ChargeUseCase Repository 呼び出し 3DS呼び出しI/F 呼び出し 3DS認証画面 3DS認証画面 認証結果 認証結果 ICチップ書き込みI/F 書き込み 書き込み ICチップ書き込み ICチップ書き込み ※資料用に編集しており、実際の構成を正確に表しているものではありません 57 Copyright © 2026 East Japan Railway Company. All rights reserved.
  40. 1 非効率的な戦略の例 E2E 手動QA リリースビルドで 週1回実行 E2E 実機テスト 通常はCIで 夜間に実行

    コンポーネント UIテスト 通常はCIで マージ前に実行 単体テスト 通常はローカルで コミット前に実行 1. 出典: Android Developers「テスト戦略」図2 ↩︎ 59 Copyright © 2026 East Japan Railway Company. All rights reserved.
  41. 1 スケーラブルなテスト戦略 リリース 候補版のテスト 統合 アプリケーションテスト スコープ 忠実性 実行時間 機能テスト

    コンポーネントテスト 分離 単体テスト 1. 出典: Android Developers「テスト戦略」図3 ↩︎ 60 Copyright © 2026 East Japan Railway Company. All rights reserved.
  42. テスト手法 手法 確かめる範囲 単体テスト 単一のメソッドやクラス コンポーネントテスト 独立させたモジュールやコンポーネント 機能テスト 複数のコンポーネント間の連携 アプリケーションテスト

    デプロイ可能なアプリ全体 リリース候補版のテスト 本番に近い環境で動かすアプリ全体 61 Copyright © 2026 East Japan Railway Company. All rights reserved.
  43. iOSのテスト手段 テスト手段 メリット デメリット Swift Testing / XCTest 高速で安定して実行 できる

    画面表示やユーザー操作は確認できない XCUITest ユーザー操作から一 連の動作を確認でき る アプリ起動や画面描画を伴うため遅く、待機タ イミングやUI変更の影響で不安定になりやすい 63 Copyright © 2026 East Japan Railway Company. All rights reserved.
  44. この発表でのテスト用語 用語 確かめる範囲 テスト手段 単体テスト 単一のメソッドやクラス Swift Testing 機能テスト 複数のコンポーネント間の連携

    Swift Testing UIテスト 画面表示とユーザー操作 XCUITest 64 Copyright © 2026 East Japan Railway Company. All rights reserved.
  45. この発表でのテスト用語 用語 確かめる範囲 テスト手段 単体テスト 単一のメソッドやクラス Swift Testing 機能テスト 複数のコンポーネント間の連携

    Swift Testing UIテスト 画面表示とユーザー操作 XCUITest 65 Copyright © 2026 East Japan Railway Company. All rights reserved.
  46. Viewは、UIテストで確かめる iOS UIテスト KMP(共通) Android UIテスト View View StateHolder StateHolder

    処理を差し替え 処理を差し替え ChargeUseCase Repository DataSource 3DS認証・ICチップ書き込み 3DS認証・ICチップ書き込み ※資料用に編集しており、実際の構成を正確に表しているものではありません 67 Copyright © 2026 East Japan Railway Company. All rights reserved.
  47. StateHolderは、単体テストで確かめる iOS KMP(共通) Android View View 単体テスト 単体テスト StateHolder StateHolder

    ChargeUseCase 処理を差し替え Repository DataSource 3DS認証・ICチップ書き込み 3DS認証・ICチップ書き込み ※資料用に編集しており、実際の構成を正確に表しているものではありません 68 Copyright © 2026 East Japan Railway Company. All rights reserved.
  48. UseCaseは、単体テストで確かめる iOS KMP(共通) Android View View StateHolder StateHolder 単体テスト ChargeUseCase

    Repository 処理を差し替え DataSource 3DS認証・ICチップ書き込み 3DS認証・ICチップ書き込み ※資料用に編集しており、実際の構成を正確に表しているものではありません 69 Copyright © 2026 East Japan Railway Company. All rights reserved.
  49. Repositoryは、単体テストで確かめる iOS KMP(共通) Android View View StateHolder StateHolder ChargeUseCase 単体テスト

    Repository DataSource 処理を差し替え 3DS認証・ICチップ書き込み 3DS認証・ICチップ書き込み ※資料用に編集しており、実際の構成を正確に表しているものではありません 70 Copyright © 2026 East Japan Railway Company. All rights reserved.
  50. DataSourceは、必要なら単体テストする iOS KMP(共通) Android View View StateHolder StateHolder ChargeUseCase Repository

    自前ロジックだけ単体テスト DataSource 処理を差し替え 3DS認証・ICチップ書き込み 3DS認証・ICチップの振る舞いを 本物同等に模倣できない 処理を差し替え 3DS認証・ICチップ書き込み ※資料用に編集しており、実際の構成を正確に表しているものではありません 71 Copyright © 2026 East Japan Railway Company. All rights reserved.
  51. ICチップの書き込みに適したテスト手法は? 手法 メリット デメリット 単体テ スト 高速・安定して繰り返せる 複数の処理がまたがるICチップへの書き 込みは確認しづらい 機能テ

    スト チャージ画面を操作せず実処 理を確認できる 画面表示・操作は確認できない UIテス ト ユーザー操作から一連の動作 を確認できる 遅く、UI変更の影響を受けやすい 72 Copyright © 2026 East Japan Railway Company. All rights reserved.
  52. ICチップの書き込みに適したテスト手法は? 手法 メリット デメリット 単体テ スト 高速・安定して繰り返せる 複数の処理がまたがるICチップへの書き 込みは確認しづらい 機能テ

    スト チャージ画面を操作せず実処 理を確認できる 画面表示・操作は確認できない UIテス ト ユーザー操作から一連の動作 を確認できる 遅く、UI変更の影響を受けやすい 73 Copyright © 2026 East Japan Railway Company. All rights reserved.
  53. 実機でUseCaseから一連の処理を確認 iOS 実機での機能テスト KMP(共通) Android 実機での機能テスト iPhone実機 Android実機 Swift Testing

    Instrumented Test ChargeUseCase 処理を差し替え Repository DataSource 3DS認証・ICチップ書き込み 3DS認証・ICチップ書き込み ※資料用に編集しており、実際の構成を正確に表しているものではありません 74 Copyright © 2026 East Japan Railway Company. All rights reserved.
  54. UseCaseから確認する理由 – 上位レイヤーだと確認対象外の影響も受ける – UIテスト: View・StateHolderの影響を受け る – StateHolderのテスト: View向けの状態管理

    の影響を受ける – チャージの処理フローだけを確認するため UseCaseを直接実行 75 Copyright © 2026 East Japan Railway Company. All rights reserved.
  55. 1 新幹線 はやぶさ 運行区間 最高速度 E5系 東北新幹線、北海道新幹線 320km/h つばさ 運行区間

    最高速度 E8系 山形新幹線、東北新幹線 300km/h 1. 出典: E5系 / E8系 - JR東日本 ↩︎ 78 Copyright © 2026 East Japan Railway Company. All rights reserved.
  56. 実機テストを走らせる「はやぶさ」と「つばさ」 はやぶさ CPU メモリ 79 Mac Studio M4 Max 16

    cores 128 GB つばさ CPU メモリ MacBook Pro M4 Pro 12 cores 48 GB Copyright © 2026 East Japan Railway Company. All rights reserved.
  57. JR東日本管内速度ランキング(登壇者調べ1) Tier 速度 車両・対象 愛称・列車名 位置づけ S 360km/h 試験 E956形

    ALFA-X 営業車両ではなく試験車両。高速営業化を見据え た試験領域。 A 320km/h 営業 E5系 / E6系 はやぶさ / こまち / はやて / やまびこ / なすの JR東日本の現行営業最速帯。主に東北新幹線高速 区間。 B 300km/h 営業 E8系 つばさ / なすの 山形新幹線向け新型。東北新幹線区間で300km/h 対応。 C 275km/h 営業 E7系 / E2系 / E3系 かがやき / はくたか / あさま / とき / たにがわ / やま びこ / なすの / つばさ JR東日本の標準的な高速帯。 D 240km/h 級以下 各形式 各列車 東京〜大宮周辺など、都市部・騒音・線形制約に よる速度制限区間。 E 130km/h 級 E3系 / E6系 / E8系 つばさ / こまち 山形・秋田新幹線の在来線直通区間。フル規格新 幹線区間ではない。 1. JR東日本の公開情報をもとに登壇者が整理した参考情報で、公式の比較資料ではありません ↩︎ 80 Copyright © 2026 East Japan Railway Company. All rights reserved.
  58. GitHub Actions の Runner GitHub-hosted runner Self-hosted runner マシン GitHubが用意

    自分たちが用意 実行環境 Jobごとに新しい環境 登録したマシンを利用 ハードウェア GitHubの構成から選択 用途に合わせて選択 社内ネットワー ク・接続機器 VPN等の接続構成が必要・手元の 機器は直接接続不可 マシンから到達・接続でき る範囲で利用可能 OS・ツールの保 守 GitHub 自分たち 81 Copyright © 2026 East Japan Railway Company. All rights reserved.
  59. Runnerの構成図 GitHub-hosted GitHub Actions Self-hosted hayabusa tsubasa M4 Max 16

    cores / Memory 128 GB M4 Pro 12 cores / Memory 48 GB Mac Studio (2025) iPhone ×3 Android ×3 82 A A MacBook Pro (14-inch, 2024) B B C C iPhone ×2 Android ×1 D E D Copyright © 2026 East Japan Railway Company. All rights reserved.
  60. Runnerの構成図 GitHub-hosted GitHub Actions Self-hosted hayabusa tsubasa M4 Max 16

    cores / Memory 128 GB M4 Pro 12 cores / Memory 48 GB Mac Studio (2025) iPhone ×3 Android ×3 83 A A MacBook Pro (14-inch, 2024) B B C C iPhone ×2 Android ×1 D E D Copyright © 2026 East Japan Railway Company. All rights reserved.
  61. Runnerの構成図 GitHub-hosted GitHub Actions Self-hosted hayabusa tsubasa M4 Max 16

    cores / Memory 128 GB M4 Pro 12 cores / Memory 48 GB Mac Studio (2025) iPhone ×3 Android ×3 84 A A MacBook Pro (14-inch, 2024) B B C C iPhone ×2 Android ×1 D E D Copyright © 2026 East Japan Railway Company. All rights reserved.
  62. Runnerの構成図 GitHub-hosted GitHub Actions Self-hosted hayabusa tsubasa M4 Max 16

    cores / Memory 128 GB M4 Pro 12 cores / Memory 48 GB Mac Studio (2025) iPhone ×3 Android ×3 85 A A MacBook Pro (14-inch, 2024) B B C C iPhone ×2 Android ×1 D E D Copyright © 2026 East Japan Railway Company. All rights reserved.
  63. Suicaの状態もテスト環境として管理 A 実機A Suicaが0枚 初めてのSuicaを作成できる状態 作成 → チャージ → 退会・払戻

    を通しで確認できる B 実機B 有効 有効 無効 別の状態 Suicaが4枚。有効・無効など、それぞれ異なる状態 1台で複数の開始条件をまかなう … 86 その他の実機 … … … … テストシナリオに応じた状態を用意する Copyright © 2026 East Japan Railway Company. All rights reserved.
  64. Suicaの状態もテスト環境として管理 A 実機A Suicaが0枚 初めてのSuicaを作成できる状態 作成 → チャージ → 退会・払戻

    を通しで確認できる B 実機B 有効 有効 無効 別の状態 Suicaが4枚。有効・無効など、それぞれ異なる状態 1台で複数の開始条件をまかなう … 87 その他の実機 … … … … テストシナリオに応じた状態を用意する Copyright © 2026 East Japan Railway Company. All rights reserved.
  65. Suicaの状態もテスト環境として管理 A 実機A Suicaが0枚 初めてのSuicaを作成できる状態 作成 → チャージ → 退会・払戻

    を通しで確認できる B 実機B 有効 有効 無効 別の状態 Suicaが4枚。有効・無効など、それぞれ異なる状態 1台で複数の開始条件をまかなう … 88 その他の実機 … … … … テストシナリオに応じた状態を用意する Copyright © 2026 East Japan Railway Company. All rights reserved.
  66. テストシナリオと実行環境を対応づける 89 テストケース Self-hosted runner 実行する端末 対象のSuica 新規作成したSuicaへチャージできる hayabusa Mac

    Studio A Suicaが0枚 登録済みのSuicaへチャージできる hayabusa Mac Studio B 有効なSuica 無効なSuicaへはチャージできない hayabusa Mac Studio B 無効なSuica その他 tsubasa MacBook Pro … … Copyright © 2026 East Japan Railway Company. All rights reserved.
  67. テストシナリオと実行環境を対応づける 90 テストケース Self-hosted runner 実行する端末 対象のSuica 新規作成したSuicaへチャージできる hayabusa Mac

    Studio A Suicaが0枚 登録済みのSuicaへチャージできる hayabusa Mac Studio B 有効なSuica 無効なSuicaへはチャージできない hayabusa Mac Studio B 無効なSuica その他 tsubasa MacBook Pro … … Copyright © 2026 East Japan Railway Company. All rights reserved.
  68. テストシナリオと実行環境を対応づける 91 テストケース Self-hosted runner 実行する端末 対象のSuica 新規作成したSuicaへチャージできる hayabusa Mac

    Studio A Suicaが0枚 登録済みのSuicaへチャージできる hayabusa Mac Studio B 有効なSuica 無効なSuicaへはチャージできない hayabusa Mac Studio B 無効なSuica その他 tsubasa MacBook Pro … … Copyright © 2026 East Japan Railway Company. All rights reserved.
  69. テストシナリオと実行環境を対応づける 92 テストケース Self-hosted runner 実行する端末 対象のSuica 新規作成したSuicaへチャージできる hayabusa Mac

    Studio A Suicaが0枚 登録済みのSuicaへチャージできる hayabusa Mac Studio B 有効なSuica 無効なSuicaへはチャージできない hayabusa Mac Studio B 無効なSuica その他 tsubasa MacBook Pro … … Copyright © 2026 East Japan Railway Company. All rights reserved.
  70. 実機テスト環境のファイル構成 ※ 実機管理に必要な観点を示すための構成例 ファイル .github/workflows/suica-devicetest.yml scenarios.yml 記載すること GitHub Actions の

    Workflow テスト内容、parameter、実行方法、固定 Target inventory.yml Runner、実機、Suica、Targetの対応関係 secrets.env 実機の識別情報とSuicaのIDの実値 dispatch.sh 実行環境を確認してKotlin製CLIを起動 94 Copyright © 2026 East Japan Railway Company. All rights reserved.
  71. scenarios.yml シナリオ名、parameter、実行方法、固定Targetを定義1 executions: ios: target: ios-charge-target workingDirectory: ios scheme: SuicaApp

    onlyTesting: SuicaTests/ChargeDeviceTests/chargeSucceeds executionGate: name: ENABLE_CHARGE_TEST value: "1" parameterEnvironment: amount: CHARGE_AMOUNT 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 96 Copyright © 2026 East Japan Railway Company. All rights reserved.
  72. scenarios.yml Androidの定義1 android: target: android-charge-target workingDirectory: . gradleTask: connectedChargeTest #

    独自タスク testClass: ChargeSuccessTest # パッケージ名は省略 executionGate: name: enableChargeTest value: "true" parameterArguments: amount: chargeAmount 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 97 Copyright © 2026 East Japan Railway Company. All rights reserved.
  73. inventory.yml TargetからSuica・実機・Runnerを特定 1 targets: ios-charge-target: kind: suica suica: iphone-a.charge android-charge-target:

    kind: suica suica: android-a.charge 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 98 Copyright © 2026 East Japan Railway Company. All rights reserved.
  74. inventory.yml TargetからSuica・実機・Runnerを特定 1 suicas: iphone-a.charge: device: iphone-a idRef: iphone-a.charge.suica-id android-a.charge:

    device: android-a idRef: android-a.charge.suica-id 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 99 Copyright © 2026 East Japan Railway Company. All rights reserved.
  75. inventory.yml TargetからSuica・実機・Runnerを特定1 devices: iphone-a: runner: hayabusa platform: ios udidRef: iphone-a.udid

    android-a: runner: hayabusa platform: android serialRef: android-a.serial 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 100 Copyright © 2026 East Japan Railway Company. All rights reserved.
  76. inventory.yml TargetからSuica・実機・Runnerを特定1 runners: hayabusa: labels: [self-hosted, macOS, ARM64, hayabusa] 1.

    資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 101 Copyright © 2026 East Japan Railway Company. All rights reserved.
  77. dispatch.sh 1 Kotlin製CLIを起動する薄いwrapper # script_dirはツール直下(解決・存在確認は省略) dist_dir="$script_dir/build/install/suica-device-test" cli="$dist_dir/bin/suica-device-test" # 引数をそのまま渡して起動 exec

    "$cli" "$@" 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 103 Copyright © 2026 East Japan Railway Company. All rights reserved.
  78. Kotlin製CLI 設定を検証し、実機テストを組み立てて実行 1 // 設定から実行計画を解決 val scenario = ScenarioResolver(...).resolve( scenarioAlias,

    scenarioDefinition, inventory, ) 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 104 Copyright © 2026 East Japan Railway Company. All rights reserved.
  79. Kotlin製CLI 設定を検証し、実機テストを組み立てて実行 1 // 指定された実行定義を取得(未定義ならエラー) val execution = scenario.executions.getValue(command.execution) //

    秘密情報を読み込む val secrets = secretSource.load(...) 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 105 Copyright © 2026 East Japan Railway Company. All rights reserved.
  80. Kotlin製CLI 設定を検証し、実機テストを組み立てて実行 1 // iOS: TEST_RUNNER_を付けてxcodebuildへ渡す // 対象IDの固定名: iOSはSUICA_ID、AndroidはsuicaId val

    environment = EnvironmentBuilder.build(execution, secrets) // OSごとのテストコマンドを構築 val testCommand = CommandBuilder.build(execution, secrets) 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 106 Copyright © 2026 East Japan Railway Company. All rights reserved.
  81. Kotlin製CLI 設定を検証し、実機テストを組み立てて実行 1 // 環境変数とともに対象実機で実行 processRunner.execute( testCommand, environment, execution.workingDirectory, execution.target,

    ) 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 107 Copyright © 2026 East Japan Railway Company. All rights reserved.
  82. Kotlin製CLI iOSのTest commandを組み立てる1 // OSに応じてテストコマンドを組み立てる when (val definition = execution.definition)

    { is IosExecutionDefinition -> { val destination = DestinationBuilder.build( execution.target, secrets, ) listOf( "/usr/bin/xcodebuild", "test", "-scheme", definition.scheme, "-destination", destination, "-only-testing:${definition.onlyTesting}", ) } 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 108 Copyright © 2026 East Japan Railway Company. All rights reserved.
  83. Kotlin製CLI AndroidのTest commandを組み立てる1 is AndroidExecutionDefinition -> // gate・金額・秘密情報から解決した対象IDも追加 listOf( "./gradlew",

    definition.gradleTask, "-Pandroid.testInstrumentationRunnerArguments" + ".class=${definition.testClass}", ) + InstrumentationArgumentsBuilder.build( execution, secrets, ) } 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 109 Copyright © 2026 East Japan Railway Company. All rights reserved.
  84. 1 実機テストCLIの処理フロー dispatch.sh Kotlin製CLI iOS / ENVはテスト側の名前 shell / 薄いwrapper

    実機テストの制御を集約 ENV 実行場所を解決 引数を解析 CMD Kotlin製CLIの存在確認 設定を読み込み・検証 tool rootを設定 Target・実機・Suicaを解決 引数を渡して起動 Test commandを構築 Runner・実機をロック 実機の接続を確認 1つのTest processを同期実行 ENABLE_CHARGE_TEST=1 CHARGE_AMOUNT=500 SUICA_ID=<Suica ID> xcodebuild test -scheme SuicaApp -destination id=<実機のudid> -only-testing:…/chargeSucceeds Android ENV CMD ANDROID_SERIAL=<実機のserial> ./gradlew connectedChargeTest -P…class=…ChargeSuccessTest -P…enableChargeTest=true -P…chargeAmount=500 -P…suicaId=<Suica ID> 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 110 Copyright © 2026 East Japan Railway Company. All rights reserved.
  85. GitHub Actionsで実機テスト実行 on: workflow_dispatch テストシナリオを選択 jobs: 111 verify plan execute

    GitHub-hosted GitHub-hosted Self-hosted Kotlin製CLIを検証 Target・実機・Runnerを解決 実機でテストを実行 設定schema・シナリオ解決・ Test command構築が、既存の 契約を壊していないか確認する テストシナリオから executionを展開し、どこで 何を実行するかを確定する planが決めたexecutionを、 対応する実機の前で 1件ずつ実行する Copyright © 2026 East Japan Railway Company. All rights reserved.
  86. workflow_dispatch 実行するテストシナリオだけを指定する 1 workflow_dispatch: inputs: scenario: description: 実行するテストシナリオ required: true

    type: choice options: - sf-charge.registered-card.success 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 112 Copyright © 2026 East Japan Railway Company. All rights reserved.
  87. jobs.verify Kotlin製CLIのロジックを検証 1 verify: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6

    - uses: ./.github/actions/setup-java-gradle - run: ./gradlew :tools:suica-device-test:check 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 113 Copyright © 2026 East Japan Railway Company. All rights reserved.
  88. jobs.plan CLIを準備する1 plan: needs: verify runs-on: ubuntu-24.04 outputs: execution_matrix: ${{

    steps.plan.outputs.execution_matrix }} steps: - uses: actions/checkout@v6 - uses: ./.github/actions/setup-java-gradle - run: ./gradlew :tools:suica-device-test:installDist 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 114 Copyright © 2026 East Japan Railway Company. All rights reserved.
  89. jobs.plan シナリオから実行環境を特定する1 - id: plan env: SCENARIO: ${{ inputs.scenario }}

    run: | matrix="$( tools/suica-device-test/dispatch.sh plan \ --scenario "$SCENARIO" )" echo "execution_matrix=$matrix" >> "$GITHUB_OUTPUT" 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 115 Copyright © 2026 East Japan Railway Company. All rights reserved.
  90. jobs.execute JobとRunnerを決める1 execute: needs: plan strategy: fail-fast: false matrix: ${{

    fromJSON(needs.plan.outputs.execution_matrix) }} name: Execute ${{ matrix.execution }} runs-on: ${{ matrix.runner_labels }} 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 116 Copyright © 2026 East Japan Railway Company. All rights reserved.
  91. execution_matrix planの出力をiOS・AndroidのJobへ展開1 { "include": [ { "execution": "ios", "runner_labels": ["self-hosted",

    "macOS", "ARM64", "hayabusa"] }, { "execution": "android", "runner_labels": ["self-hosted", "macOS", "ARM64", "hayabusa"] } ] } 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 118 Copyright © 2026 East Japan Railway Company. All rights reserved.
  92. jobs.execute Runner上でCLIを準備する1 steps: - uses: actions/checkout@v6 - uses: ./.github/actions/setup-java-gradle -

    run: ./gradlew :tools:suica-devicetest:installDist 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 119 Copyright © 2026 East Japan Railway Company. All rights reserved.
  93. jobs.execute シナリオと実行定義をCLIへ渡す1 - name: Execute device test env: SCENARIO: ${{

    inputs.scenario }} EXECUTION: ${{ matrix.execution }} run: | tools/suica-device-test/dispatch.sh run \ --scenario "$SCENARIO" \ --execution "$EXECUTION" \ --execute 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 120 Copyright © 2026 East Japan Railway Company. All rights reserved.
  94. 実機自動テストCIの全体像 設定ファイル GitHub-hosted scenarios.yml workflow̲dispatch → verify → plan テスト内容・固定Target

    dispatch.sh plan が設定を読み、実行計画を決める inventory.yml execution̲matrix(2要素) 実機・Suica・Runner Self-hosted secrets.env 識別情報の実値 121 execute(ios) execute(android) dispatch.sh run dispatch.sh run 秘密情報・ロック・接続確認 秘密情報・ロック・接続確認 xcodebuild Gradle iPhone端末 + Suica Android端末 + Suica Copyright © 2026 East Japan Railway Company. All rights reserved.
  95. TestEnvironment 環境変数をテスト用の型へ集約 1 enum TestEnvironment { static var isChargeTestEnabled: Bool

    { ProcessInfo.processInfo.environment[ "ENABLE_CHARGE_TEST" ] == "1" } static var targetSuicaID: String { /* SUICA_IDの取得・検証は省略 */ } static var chargeAmount: Int { /* ... */ } } 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 123 Copyright © 2026 East Japan Railway Company. All rights reserved.
  96. ChargeDeviceTests 本番実装を明示設定して使用(設定処理は省略) 1 @Suite(.serialized) struct ChargeDeviceTests { @Dependency(\.getSuicasUseCase) var getSuicasUseCase

    @Dependency(\.getBalanceUseCase) var getBalanceUseCase @Dependency(\.chargeUseCase) var chargeUseCase 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 124 Copyright © 2026 East Japan Railway Company. All rights reserved.
  97. ChargeDeviceTests テストは明示的に有効化した場合のみ実行 1 @Test( // 通常のテスト実行ではスキップ .enabled(if: TestEnvironment.isChargeTestEnabled) ) func

    chargeSucceeds() async throws { 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 125 Copyright © 2026 East Japan Railway Company. All rights reserved.
  98. ChargeDeviceTests 対象のSuicaを選択1 // 実行環境から対象Suicaとチャージ金額を取得 let suicaID = TestEnvironment.targetSuicaID let amount

    = TestEnvironment.chargeAmount // 実機内のSuicaからIDが一致する対象を特定 let suicas = try await getSuicasUseCase() let suica = try #require( suicas.first { $0.id == suicaID } ) 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 126 Copyright © 2026 East Japan Railway Company. All rights reserved.
  99. ChargeDeviceTests チャージを実行(状態復帰の後処理は省略)1 let before = try await getBalanceUseCase(suica) try await

    chargeUseCase( // ← チャージを実行! suica: suica, amount: amount ) let after = try await getBalanceUseCase(suica) #expect(after - before == amount) 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 127 Copyright © 2026 East Japan Railway Company. All rights reserved.
  100. 実機テストの依存グラフ 1 Swift Test @Dependency(\.chargeUseCase) ChargeUseCase(本番実装) 本番実装を明示設定(設定は省略) 本番実装の依存グラフ(接続先は開発環境) API Client

    実際のチャージ要求 3DS Bridge WKWebViewで認証 DataSource PassKitをラップし、実機上のSuica・残高・状態を取得 CIでの無人完了条件は未確定 1. 資料用に編集しており、実際の構成を正確に表しているものではありません ↩︎ 128 Copyright © 2026 East Japan Railway Company. All rights reserved.
  101. 実機自動テストは3つの設計で支える アーキテクチャ テスト戦略 CI運用 View / StateHolder UseCase Repository /

    DataSource KMPに限らず レイヤーで責務を分け 単体でテストできる構造にする 131 単体テスト 実機テスト 各レイヤーを単体テストし 実機機能テストはSwift Testingから 実行する構成を目指す 物理実機と端末内の状態を テスト環境として管理する Copyright © 2026 East Japan Railway Company. All rights reserved.
  102. 今後の運用課題 – 端末・Suicaの状態管理 – 開始条件の自動確認 – 自動復帰できない場合の対応 – 複数端末での並列実行 –

    OSバージョンごとの端末確保 – 端末の充電・保守 132 Copyright © 2026 East Japan Railway Company. All rights reserved.