テストと検証
アプリ向けの検証物はすべて App/Tests/ 配下にまとめます(ADR-0001)。 実行するユニットテストと、結合・通し・シナリオ設計の箱を同じ親の下に置き、 製品コード(App/Tokfuel*)と運営物(Site / Docs / Scripts)を分けます。 このページに、配置の意味と検証の進め方を載せます。
ディレクトリ構成
App/Tests/
UnitTests/ … Swift Testing。swift test の対象
IntegrationTests/ … 結合テスト(いまは箱のみ)
E2E/ … 通し実装(swift test 対象外)
TestDocs/ … シナリオ設計(実行しない文書)
README.md … 親ディレクトリの説明
UnitTests
ヘッドレスで検証できるロジックをここに置きます。Package.swift の TokfuelTests がこのパスを指し、swift test で実行します。新しいロジックを足したら、同じ層の 近くにテストを足します。
実ユーザーの状態(~/Library/Application Support/Tokfuel)に触れるテストは書きません。
カバレッジ(行)
swift test --enable-code-coverage のスナップショット(2026-08-08)。App/ 配下のみ。依存の checkouts は含みません。
ユニットテスト 367 件 / 63 スイート
App 合計 2821 / 7800 行(36.2%)
TokfuelCursor
TokfuelCore
TokfuelSettings
TokfuelBudget
TokfuelStore
TokfuelClaude
TokfuelCodex
TokfuelAnalytics
TokfuelUI
Tokfuel (app)
TokfuelUI と実行ファイル(Tokfuel)は SwiftUI の見た目寄りなので行カバレッジは低く出ます。見た目は ui-preview、ロジックは UnitTests で担保します。
IntegrationTests
結合テスト用の箱です。いまは README だけのプレースホルダです。追加するときは 別の test target を切るか Package.swift に明示的に足し、既定の UnitTests パスには 混ぜません。
E2E
通しテスト実装の置き場です。swift test の対象外で、別ランナーを想定します。 Maestro や Appium などのモバイル向けスタックは持ち込みません。macOS メニューバーアプリ向けの起動スモークや画面到達など、必要な範囲だけを後続 Issue で 足します。シナリオ設計の正本は TestDocs 側です。
TestDocs
テストシナリオ設計を置く場所です。実行コードではありません。観点の正本をここに 置き、起票 → 実装 → ステータス更新の流れで進めます。テンプレートや観点 ID の規約、 個別シナリオは後続 Issue で足す前提で、配置の箱を先に確保しています。
UnitTests がカバーしている領域
Store / 合算・表示整形
UsageStore — 合計、チャート、モデル別内訳の保持と更新
CostChart / CostDisplayMode / Formatting — 表示用の整形とモード
MenuBarReadout / MenuBarImage — メニューバーの読み出しと描画
RefreshScheduler — 待機時とアクティブ時の更新間隔
Claude(retok)
RetokReport — レポートのデコード
TranscriptScanner — トランスクリプト走査
AdvicePrompt — 節約ヒント用プロンプト
Cursor / Codex
CursorDashboardService / CursorPricing / CursorPricingService — ダッシュボード取得と価格表
CursorCostDriver / CursorAdvice — コスト推定とアドバイス
CodexCostDriver — Codex CLI セッション由来のコスト
Budget / Settings / その他
BudgetMonitor — 月次・日次しきい値と一度きりの通知
AppSettings — UserDefaults ベースの設定
CSVExportService — 端末上だけの CSV 書き出し
UpdateChecker — Releases ポーリングとダウンロード境界
HTTPClient / RemoteDiagnosticsPolicy / UsageEventLog — 通信と診断ポリシー
ScreenshotRenderer — ui-preview 用フィクスチャ画面の描画
ローカルでの検証ゲート
swift test— App/Tests/UnitTests を実行する。PR 前の基本ゲート。swift build -c release— Scripts/build.sh がパッケージする構成に近いリリースビルド。bash Scripts/build.sh— Tokfuel.app を /Applications に配置して起動し、実行時に見える変更を観察する。未検証の動作を動くと主張しない。
CI
.github/workflows/ci.yml が、App/Tokfuel・App/Tests・Package.swift などを触った PR でユニットテストを実行します。Docs / Site のみの変更ではそのジョブは走りません。 リリース構成のビルドは Scripts/build.sh や配布フロー側で確認します。
UI プレビュー(スクリーンショット)
レビュアーが新しい UI を見られないままにしないための約束です。PopoverView、 SettingsView、AboutView、および単独で見せる新規 View(同意ダイアログやアラートなど)を 追加または変更するときは、同じ PR で次も更新します。
ScreenshotRenderer.allScreens() のフィクスチャ画面
ui-preview.yml の ORDER / screen_title リスト
ui-preview ラベルが付いた PR では、新しい状態を実際に描画できます。ライブな シングルトン経由でしか到達できないビュー(ネットワーク応答や実インストールパスに 依存するもの)には、注入可能なフィクスチャを用意します(UpdateChecker.preview など)。 ダイアログやパネルの文面は SwiftUI の表示 View に置き、ランタイムとプレビューで 同じ View を使います。
担保の優先
ヘッドレスで足りるロジックは UnitTests を先に足します。画面の見た目や到達は ui-preview(VRT 相当)と、必要な範囲の E2E で補います。シナリオの「何を担保するか」は TestDocs に書き、実装は UnitTests / IntegrationTests / E2E に振り分けます。