XCTest/XCUITestを用いたiOSアプリのテスト設計支援スキル。テスト戦略立案、モック/スタブ設計、テストデータ管理、カバレッジ分析を包括的にサポート。Use when: iOSテスト設計、XCTest実装、UITest作成、テストカバレッジ向上、テスト戦略立案、テストダブル設計。
Provides comprehensive iOS test design support using XCTest/XCUITest. Use when designing tests, implementing XCTest, creating UI tests, improving coverage, or planning test strategies.
/plugin marketplace add CAPHTECH/claude-marketplace/plugin install apple-platform-plugin@caphtech-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/test-data.mdreferences/test-doubles.mdreferences/xctest-patterns.mdreferences/xcuitest-patterns.mdXCTestおよびXCUITestを活用したiOSアプリケーションのテスト設計を支援するスキル。 デトロイト学派寄りのアプローチを採用し、実際のコンポーネント連携をテストすることで、信頼性の高いテストスイートを構築する。
以下の状況でこのスキルを起動する:
| 評価項目 | 確認内容 |
|---|---|
| 依存性注入 | コンストラクタ/プロパティ経由で差し替え可能か |
| 副作用の分離 | I/O操作がプロトコル経由で抽象化されているか |
| 状態の観測 | 内部状態の変化を外部から検証可能か |
| 決定論性 | 同一入力に対して同一出力が保証されるか |
╱╲
╱ ╲ E2E Test(XCUITest): 主要シナリオのみ
╱────╲
╱ ╲ Integration Test: コンポーネント間連携
╱────────╲
╱ ╲ Unit Test: ビジネスロジック中心
╱────────────╲
| レベル | 対象 | テストダブル | 実行頻度 |
|---|---|---|---|
| Unit | ビジネスロジック、ViewModel、Utility | スタブ/モック | 常時 |
| Integration | UseCase + Repository、View + ViewModel | スタブ(外部境界のみ) | PR/CI |
| UI | 主要ユーザーフロー | なし(実環境に近づける) | デイリー/リリース |
詳細は references/xctest-patterns.md を参照。
final class SampleTests: XCTestCase {
// MARK: - Properties
private var sut: SystemUnderTest!
private var mockDependency: MockDependency!
// MARK: - Setup/Teardown
override func setUp() {
super.setUp()
mockDependency = MockDependency()
sut = SystemUnderTest(dependency: mockDependency)
}
override func tearDown() {
sut = nil
mockDependency = nil
super.tearDown()
}
// MARK: - Tests
func test_methodName_condition_expectedBehavior() {
// Given(前提条件)
let input = ...
// When(実行)
let result = sut.method(input)
// Then(検証)
XCTAssertEqual(result, expected)
}
}
test_<対象メソッド>_<条件>_<期待される振る舞い>
例:
test_login_withValidCredentials_returnsSuccess
test_fetchUser_whenNetworkError_throwsError
test_calculate_withNegativeInput_returnsZero
詳細は references/test-doubles.md を参照。
| 種類 | 用途 | 実装例 |
|---|---|---|
| Stub | 事前定義した値を返す | stub.returnValue = expectedData |
| Mock | 呼び出しを検証する | XCTAssertTrue(mock.didCallMethod) |
| Fake | 軽量な実装 | InMemoryUserRepository |
| Spy | 呼び出し履歴を記録 | spy.calledArguments |
// 抽象化されたプロトコル
protocol UserRepositoryProtocol {
func fetch(id: String) async throws -> User
}
// 本番実装
final class UserRepository: UserRepositoryProtocol { ... }
// テストダブル
final class MockUserRepository: UserRepositoryProtocol {
var fetchResult: Result<User, Error> = .success(User.stub)
var fetchCallCount = 0
var lastFetchedId: String?
func fetch(id: String) async throws -> User {
fetchCallCount += 1
lastFetchedId = id
return try fetchResult.get()
}
}
詳細は references/xcuitest-patterns.md を参照。
// Page Object
final class LoginPage {
private let app: XCUIApplication
var emailField: XCUIElement { app.textFields["email"] }
var passwordField: XCUIElement { app.secureTextFields["password"] }
var loginButton: XCUIElement { app.buttons["login"] }
init(app: XCUIApplication) {
self.app = app
}
func login(email: String, password: String) -> HomePage {
emailField.tap()
emailField.typeText(email)
passwordField.tap()
passwordField.typeText(password)
loginButton.tap()
return HomePage(app: app)
}
}
| 要素 | 命名規則 | 例 |
|---|---|---|
| 画面 | <screen>_screen | login_screen |
| ボタン | <action>_button | submit_button |
| テキストフィールド | <field>_field | email_field |
| ラベル | <content>_label | error_label |
| セル | <item>_cell_<index> | user_cell_0 |
詳細は references/test-data.md を参照。
enum UserFactory {
static func make(
id: String = UUID().uuidString,
name: String = "Test User",
email: String = "test@example.com",
isActive: Bool = true
) -> User {
User(id: id, name: name, email: email, isActive: isActive)
}
static var activeUser: User { make(isActive: true) }
static var inactiveUser: User { make(isActive: false) }
}
Tests/
├── Fixtures/
│ ├── JSON/
│ │ ├── user_response.json
│ │ └── error_response.json
│ └── Stubs/
│ └── UserStub.swift
| レベル | 目標 | 説明 |
|---|---|---|
| 行カバレッジ | 80%以上 | 実行された行の割合 |
| 分岐カバレッジ | 70%以上 | if/switch分岐の網羅 |
| 重要パス | 100% | ビジネスクリティカルなパス |
Cmd + U でテスト実行# テスト設計書: <機能名>
## 1. テスト対象
- クラス/構造体: `ClassName`
- 責務: 〇〇を行う
## 2. テスト戦略
- テストレベル: Unit / Integration / UI
- テストダブル: 使用する依存のリスト
## 3. テストケース一覧
| ID | カテゴリ | テスト内容 | 期待結果 |
|----|---------|----------|---------|
| TC-001 | 正常系 | ... | ... |
| TC-002 | 異常系 | ... | ... |
## 4. テストダブル設計
- MockXxx: 〇〇の呼び出しを検証
- StubYyy: 〇〇の値を返す
## 5. テストデータ
- Factory: XxxFactory
- Fixture: xxx_response.json
import XCTest
@testable import TargetModule
final class FeatureTests: XCTestCase {
// 上記パターンに従ったテストコード
}
Date() 直接使用ではなく注入するreferences/xctest-patterns.md: XCTestパターン集references/xcuitest-patterns.md: XCUITestパターン集references/test-doubles.md: テストダブル設計ガイドreferences/test-data.md: テストデータ管理ガイドThis skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.