qa-testing-ios について
XCTest、XCUITest、Swift Testing、Xcode ツールを扱う iOS 開発者や QA 向けのテストスキルです。テストの不安定さを抑え、シミュレーター、実機、リリース検証で確認できる範囲を区別します。
主な機能
- 01iOS の単体・統合・UI テスト実行
- 02xcresult による結果確認
- 03シミュレーターと実機のテスト先管理
- 04不安定さの抑制と環境分離
- 05ローカライズと E2E テストの計画
活用シーン
- 01PR 向けの軽量なシミュレーター検証を設定
- 02失敗したテストを個別に再現・診断
- 03ハードウェアや配信経路に依存する機能を検証
- 04多言語 UI のテスト範囲を計画
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vasilyu1983/ ai-agents-public --skill qa-testing-iosインストール後、Claude Code で/qa-testing-iosを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
learnings.consolidated.mdlearnings.mdagents/openai.yamlassets/template-ios-ui-test-stability-checklist.mddata/sources.jsonreferences/e2e-harness-and-selectors.mdios-ci-general.mdios-ci-github-actions.mdios-version-and-vision-pro.mdsimulator-commands.mdsnapshot-testing-ios.mdswift-testing.mdxctest-patterns.mdxcuitest-patterns.mdscripts/README.mdxcresult_to_junit.pyscripts/tests/test_xcresult_to_junit.pyscripts/tests/fixtures/xcode27_summary.jsonxcode27_tests.json詳細
QA テスト(iOS)
XCTest、XCUITest、Swift Testing、xcodebuild、xcresult、simctl を対象とした、精度の高い iOS テスト実行とフレーク制御です。
ネイティブ iOS の書き換えや Codex / Claude Code による実装サイクルの一環として作業する場合は、このスキルを software-ios-native と併用してください。
主なドキュメント:
- https://developer.apple.com/documentation/xctest
- https://developer.apple.com/documentation/testing
- https://developer.apple.com/documentation/xcode/testing-your-apps-in-xcode
- https://developer.apple.com/documentation/xcode/simctl
- https://developer.apple.com/documentation/xcode-release-notes/xcode-27-release-notes
クイックリファレンス
| 必要な内容 | 参照先 |
|---|---|
| iOS テストのワークフローを実行する | ## Workflow |
| 現在のデフォルトとコマンドパターンを読み込む | ## Defaults と ## xcodebuild Patterns |
| フレークと実行先を制御する | ## Flake Control |
| テンプレートとリファレンスを読み込む | ## Navigation |
リリース検証の境界
- 機能が配布用の署名、実機、APNs、カメラ、生体認証、購入、またはバックグラウンド実行に依存する場合、シミュレーターの成功やアーカイブの成功を iOS リリースの完全な証明と見なさないでください。
- そのような場合は、本番の動作に合ったリリース経路を必須としてください。署名済みアーカイブ、該当する場合はベータ版/配布チャネルでの検証、そして実機でユーザーから確認できる結果が含まれます。
- プロジェクト固有のロールアウト手順、バックエンドのエンドポイント、テスターアカウントのクリーンアップ、内部ランブックは、この移植可能なコアに含めないでください。プロジェクトのドキュメントまたは対象を限定したリファレンスに記載してください。
- リリース CI とアーカイブ経路の確認には references/ios-ci-general.md を、配布チャネルの計画には qa-testing-mobile/references/release-and-rollout.md を使用してください。
デフォルト
- 新しい単体テストと統合テストには、プロジェクトですでに XCTest が標準化されている場合を除き、Swift Testing を優先してください。
- UI テストとパフォーマンステストには、引き続き XCTest/XCUITest を使用してください。
- PR ゲートでは、
xcresultアーティファクトを常に有効にした、シミュレーターでの最小限のスモークテストを実施してください。 - リリースへの信頼性を高めるため、ハードウェアの動作が関係する場合にのみ実機テストを追加してください。
- フレークへの対処方針:まずフレークの発生を確認してから、テストの分離、待機処理、または環境の差異を修正してください。再試行はデバッグの補助であり、成功の判定基準ではありません。
- ロケール、地域、タイムゾーン、権限、アプリの状態は、自動化で明示する必要があります。
- フレームワークをまたぐアサーションは、相互運用モードによって失敗を検出できない場合があります。テストが検出されたからといって、アサーションにも互換性があると決めつけないでください。references/swift-testing.md に記載されたバージョン固有のモードと CI チェックを使用してください。
- iOS 26 SDK の採用後は、既存のスナップショットのベースラインを Liquid Glass のレンダリングと比較し、影響を受けるベースラインを再生成してください。差分をそれぞれ確認してから採用してください。
収集する入力情報
- Xcode のエントリーポイント:
-workspaceまたは-project -schemeと任意の-testPlan- 実行先の方針:シミュレーター、実機、または両方
- 必要なフック:起動引数、起動環境、テストデータ、認証のバイパス、アニメーションの切り替え
- 必要なアーティファクト:
xcresult、カバレッジ、スクリーンショット、ログ、診断情報 - CI 環境:ローカル、GitHub Actions、Xcode Cloud、またはセルフホストの macOS
- UI の観察結果を信頼する前に、アプリのアンインストール、新規インストール、起動を改めて確認する必要があるか
- タスクに、実機での検証が必要な配布チャネルまたはハードウェア固有の動作が含まれるか
クイックスタート
| コマンド | 目的 |
|---|---|
xcodebuild -list -workspace MyApp.xcworkspace | スキームを一覧表示します |
xcodebuild -scheme MyApp -showdestinations | 有効なデスティネーションを表示します |
xcodebuild -scheme MyApp -showTestPlans | 利用可能なテストプランを表示します |
xcrun xctrace list devices | 実機とシミュレーターのデバイスを一覧表示します |
xcrun simctl list devices available | 利用可能なシミュレーターを一覧表示します |
xcrun simctl boot "<simulator-name>" | シミュレーターを起動します |
xcrun simctl bootstatus booted -b | 起動完了を待ちます |
xcrun simctl uninstall booted <bundle-id> | スモークテストの前に、古いインストール済みアプリを削除します |
select-simulator.sh の手順で、起動中の UDID を .simulator-udid(gitignore 対象)に保存します | 停止スクリプトはこのファイルを読み込み、xcrun simctl shutdown <UDID> と xcrun simctl terminate <UDID> <bundle-id> を呼び出して、起動したシミュレーターだけを終了します。無関係な開発用/CI 用シミュレーターまで一括終了してしまう pkill -f Simulator を置き換えます。UDID ファイルは、実行スクリプトと停止スクリプト間の取り決めです。 |
xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=<simulator-name>,OS=latest' -resultBundlePath TestResults.xcresult | シミュレーターでテストを実行します |
xcodebuild test -scheme MyApp -destination 'platform=iOS,id=<UDID>' -resultBundlePath TestResults.xcresult | デバイスでテストを実行します |
xcodebuild build-for-testing ... の後に xcodebuild test-without-building ... | 再実行を高速化します |
xcrun xcresulttool get test-results summary --path TestResults.xcresult | 成否と件数を表示します(ツリーは get test-results tests で表示できます)。非推奨のオブジェクト API では --legacy が必要です。選択中の Xcode で xcrun xcresulttool get object --help を確認してください |
xcodebuild ... -destination "generic/platform=iOS" build | シミュレーターを使わずにコンパイルのみを行います。シミュレーターサービスが利用できない場合や、コンパイル/リンクの証明だけが必要な場合に使用します |
xcodebuild archive -scheme MyApp -destination 'generic/platform=iOS' -archivePath MyApp.xcarchive | アーカイブ/署名の手順を実行します(.xcarchive を生成します。-exportArchive で .ipa を作成します)。リリース候補を準備完了と判断する前に実行してください |
ワークフロー
- まず、ビルド入力を確定します。ワークスペースまたはプロジェクト、スキーム、テストプラン、デスティネーション、必要な起動フックを確認します。
- 環境を再現可能にします。シミュレーターの起動、権限、ロケール、地域、アプリ状態のリセットを行います。
- 現在のバイナリが実際に画面に表示されているかどうかがタスクに関わる場合は、スクリーンショットや UI テストの失敗を解釈する前に、アンインストール/インストール/起動を新たに行うスモークテストを実施します。
- シミュレーターのスクリーンショットのパスが存在しないか期限切れの場合は、証拠がないのではなく、ツールの問題として扱います。現在のシミュレーターで再撮影するか、報告された画面上の症状とソースの調査をもとに、次に確認すべき点を絞り込みます。
- タスクにプッシュ通知、購入、ディープリンクなど、配布チャネルに関わる動作が含まれる場合は、転送の証明とユーザーに見える結果の証明を分け、必要に応じて実機で確認します。
- コンパイル、テスト、アーカイブ、インストール/起動、TestFlight、ユーザージャーニーの証拠はそれぞれ区別します。ソースリビジョン、スキーム/構成、アーカイブまたはアプリの識別情報、デスティネーション/OS、正確なテストプランまたはセレクター、結果バンドルのパスを記録し、最後に観測できた段階までをリリースの根拠とします。
- アーティファクトを有効にして実行します。
-resultBundlePathを指定し、タスクに必要な場合のみカバレッジや診断情報を追加します。 - まず
xcresultから原因を調査し、次に-only-testingを使って失敗したテストを1つだけ再現します。 - CoreSimulatorService が「Connection refused」を返した場合は、同じデスティネーションでの再試行をやめます。コンパイルのみの証明には
generic/platform=iOSを使い、サービスの復旧は software-ios-runtime-debugging に依頼します。 - バックエンドと連携するフローでは、references/e2e-harness-and-selectors.md にあるアカウント再作成、キャッシュ分離、Web/API の整合性チェックリストを実行します。
- 再実行で成功した場合は、責任者の割り当てと根本原因の修正が必要な不安定なテストとして扱います。
実行時の証明範囲
- アプリをビルドしてインストールできる状態になった後のテスト実行、
xcresult、デスティネーション、フレーク制御には、このスキルを使用します。 - 問題の核心が古いインストール、シミュレーターの状態のずれ、不正な
.appバンドル、実行可能ファイルの欠落、インストールや起動の失敗にある場合は、software-ios-runtime-debugging に案内してください。 - アプリを確実にインストールまたは起動できない場合、まず実行時デバッグの問題として扱い、その次にテストの問題として扱います。
- シミュレーターまたは明示的に署名なしでビルドしたものでは、デバイス署名を検証できません。開発用署名を付けたデバイスビルドで検証できるのは、そのデスティネーションに対する開発用署名であり、配布用署名、エクスポート、TestFlight での処理、リリースアーティファクトのインストール可能性は検証できません。アーカイブが成功しただけでは、エクスポート、インストール、起動を検証したことにはなりません。また、シミュレーターでのパスでは、APNs、StoreKit、エンタイトルメント、バックグラウンドモード、カメラ、生体認証、その他のデバイスや配信チャネルに依存する動作は検証できません。
xcodebuild のパターン
# Enumerate before an expensive run
xcodebuild test \
-scheme MyApp \
-testPlan Smoke \
-destination 'platform=iOS Simulator,name=<simulator-name>,OS=latest' \
-enumerate-tests \
-test-enumeration-format json
# Target one test
xcodebuild test \
-scheme MyApp \
-destination 'platform=iOS Simulator,name=<simulator-name>,OS=latest' \
-only-testing:MyAppUITests/LoginFlowTests/testHappyPath \
-resultBundlePath TestResults.xcresult
# Parallelize only when the suite is isolation-safe
xcodebuild test \
-scheme MyApp \
-destination 'platform=iOS Simulator,name=<simulator-name>,OS=latest' \
-parallel-testing-enabled YES \
-maximum-parallel-testing-workers 4 \
-resultBundlePath TestResults.xcresult
# Controlled retry for CI triage
xcodebuild test \
-scheme MyApp \
-destination 'platform=iOS Simulator,name=<simulator-name>,OS=latest' \
-retry-tests-on-failure \
-test-iterations 2 \
-test-repetition-relaunch-enabled YES \
-collect-test-diagnostics on-failure \
-resultBundlePath TestResults.xcresult
# Prove a flake locally
xcodebuild test \
-scheme MyApp \
-destination 'platform=iOS Simulator,name=<simulator-name>,OS=latest' \
-only-testing:MyAppUITests/LoginFlowTests/testHappyPath \
-run-tests-until-failure \
-test-iterations 25
フレーク制御
- スリープよりも、
waitForExistence、期待値、状態ベースのアサーションを優先してください。 - アプリで可能な場合は、UI テストの実行時にアニメーションを無効化するか、減らしてください。
- UI テストでは、サードパーティとの境界をスタブ化またはリダイレクトし、稼働中の外部サービスに依存しないでください。
- テスト間で権限とアプリの状態をリセットしてください。
- ロケールがアサーションに影響する場合は、
-testLanguageと-testRegionを固定してください。 - デバイスクラス、ロケール、環境をまたぐマトリックス形式のカバレッジには、テストプランを使用してください。
- UI テストスイートは軽量に保ってください。ビジネスロジックのカバレッジの大部分は、より下位のレイヤーに配置してください。
- 多言語対応アプリでは、レイヤーごとのカバレッジに qa-testing-mobile/references/localization-testing.md を使用してください。
ローカライズとビジュアルリグレッションの検証
- 文字列カタログまたは生成されたアクセサーの検索で発生するキー欠落によるクラッシュは、テスト可能な不具合であり、許容できる実行時アサーションではありません。UI の仕上げに戻る前に、カタログのカバレッジを追加するか実行してください。
- キーの存在と翻訳の品質の両方を確認してください。ユーザーに表示される文言について、ロケールファイルに英語のフォールバックが含まれている場合、ローカライズのゲートは不合格です。
- 機能に新しい UI 文言を追加した場合は、まずすべてのリリース対象ロケールで新しいキーのみに絞ったキーと値のチェックを実行し、その後、より広範な静的キーのカバレッジスイートを実行してください。
- ロケールのカバレッジに加えて、ドイツ語、ロシア語、日本語、アラビア語など、リスクの高いロケールでは狭い幅でのビジュアルスモークテストを実施してください。コンテナーの幅、折り返し、オーバーレイによる遮蔽は、別個のデザイン上の細部ではなく、ローカライズテストの一部です。
- データビジュアライゼーションが密な画面では、コントロール、ヘルプ/情報カード、詳細表示の操作要素が主要な図を覆わず、ズームやフィルターの変更後も使用できることを確認する、対象を絞ったスモークテストを含めてください。
決定論的な E2E ハーネス
認証、オンボーディング、課金など、バックエンドと連携するフローでは、稼働中の認証情報を使うより、フィクスチャに基づく起動環境ハーネスを優先してください。ユーザーのバリエーションを明示し、フィクスチャ用の分岐を実際の処理と同じ関数内に置いてください。また、.accessibilityIdentifier() の文字列はテスト契約の一部として扱ってください。
以下については、references/e2e-harness-and-selectors.md を読み込んでください。
- 標準的な起動環境フィクスチャのパターン
- ハーネスのルールとリセットフックの運用規律
- 識別子とラベルのセレクターに関するルール
- 新しい E2E テストスイートを追加するためのアトミックコミットのパターン
- 複数アカウントとバックエンドとのパリティに関するエッジケース
テスト計画の構成
Xcode のテスト計画(.xctestplan)では、実行するテスト、その設定、実行環境を制御します。マトリックス形式のテスト実行を管理するには、次のように使います。
- スモークプラン:PR ゲート向けの、重要なクリティカルパスに絞ったテストです。高速で安定しており、デバイスのマトリックスは最小限です。
- フルプラン:夜間またはリリース候補の実行向けに、ユニット、統合、UI の各テストをすべて実行します。
- ロケールプラン:同じ UI テストに対して、設定ごとに異なる
-testLanguage/-testRegionのオーバーライドを適用します。 - テスト計画はスキームと並べてプロジェクトディレクトリに保管します。
xcodebuildでは-testPlan PlanNameを指定して参照します。 - 計画内の各設定では、起動引数、環境変数、有効にするテストを個別にオーバーライドできます。
- 複雑な単一の複数設定プランより、個別のプランを使うことをおすすめします。実行、問題の切り分け、保守が容易になります。
iOS 向け AI エージェントテスト
AI ネイティブなテストツール(Maestro MCP など)は XCUITest を補完するものです。PR ゲート向けの決定論的なスモークテストは XCUITest で維持してください。ツールの位置づけと選定フレームワークについては、qa-testing-mobile/references/ai-native-testing.md を読み込んでください。ベンダーの機能に関する説明は頻繁に変わるため、推奨する前にベンダーの最新ドキュメントで確認してください。
使用しないケース
| シナリオ | 代わりに使用 |
|---|---|
| 製品アーキテクチャ、アプリの実装、SwiftUI への書き換え、または Xcode エージェントのワークフロー | software-ios-native |
| ビルド/インストールの失敗、アプリが古い可能性、バンドルの実行ファイルの欠落、またはシミュレーター/パッケージのデバッグ | software-ios-runtime-debugging |
| クロスプラットフォームのモバイルテスト戦略 | qa-testing-mobile |
| リリース全体の品質戦略 | qa-testing-strategy |
リソース
| リソース | 目的 |
|---|---|
| references/e2e-harness-and-selectors.md | 決定論的なフィクスチャハーネス、セレクターの適切な運用、E2E のランディングルール |
| references/swift-testing.md | Swift Testing のアサーション、特性、確認、SDK に依存する機能、XCTest からの移行 |
| references/xctest-patterns.md | ユニット、統合、パフォーマンステスト向けの XCTest パターン |
| references/xcuitest-patterns.md | XCUITest の作成と不安定さの制御 |
| references/simulator-commands.md | 自動化で使う価値のある最新の simctl コマンド |
| references/snapshot-testing-ios.md | 最新の注意点を踏まえたスナップショットテスト |
| references/ios-ci-general.md | アーカイブパスと新規クローンの確認を含む、プロバイダーに依存しない iOS CI のガイダンス |
| references/ios-ci-github-actions.md | GitHub Actions の詳細とランナーのドリフト確認 |
| references/ios-version-and-vision-pro.md | iOS 26 の Liquid Glass がスナップショットに与える影響、visionOS 26 のデスティネーション構文、Reality Composer Pro アセットのテスト、ハンドトラッキングのシミュレーター制限 |
| ../qa-testing-mobile/references/localization-testing.md | モバイル UI とバックエンド配信コンテンツを対象とする、段階的なローカライゼーションカバレッジ |
| ../qa-testing-accessibility/SKILL.md | アクセシビリティに特化した QA ゲート、スクリーンリーダーのカバレッジ、適合性の範囲に関するガイダンス |
| data/sources.json | 厳選した外部リファレンス |
スクリプト
| スクリプト | 目的 |
|---|---|
| scripts/xcresult_to_junit.py | .xcresult を JUnit XML に変換します(Xcode 16 以降、Xcode 27 のフィクスチャを使用。標準ライブラリのみ)。Test Case ノードを数え、その子ノードから失敗を読み取り、カウントが xcresulttool get test-results summary と一致しない場合は 4 で終了します。回帰テスト:python3 -m unittest discover -s scripts/tests |
| scripts/README.md | 使用ガイドと CI 統合例(GitHub Actions、Bitrise) |
テンプレート
| テンプレート | 目的 |
|---|---|
| assets/template-ios-ui-test-stability-checklist.md | UI テストの決定性を確認するためのレビュー用チェックリスト |
ナビゲーション
- 基本の手順については、
## Workflow、## xcodebuild Patterns、## Flake Controlを参照してください - 詳細な資料については、
## Resourcesと## Templatesを参照してください
学びのループ
過去の決定や落とし穴が関係する場合は、learnings.consolidated.md があれば参照してください。必要な履歴がある場合、または利用可能な代替資料としてのみ、learnings.md を使用してください。それ以外の場合は、どちらも参照しないでください。
適用後、覚えておく価値のあるパターン、防止すべきミス、または意外だった分野の事実に遭遇した場合は、agents-skills-feedback-loop/scripts/append_learning.py を使って、日付入りの箇条書きを 1 件 learnings.md に追記してください。SKILL.md 自体は変更しないでください。