テストと検証

アプリ向けの検証物はすべて 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

92% 695/753

TokfuelCore

78% 619/794

TokfuelSettings

74% 168/228

TokfuelBudget

62% 91/146

TokfuelStore

49% 448/910

TokfuelClaude

46% 132/284

TokfuelCodex

43% 15/35

TokfuelAnalytics

29% 17/59

TokfuelUI

15% 602/4021

Tokfuel (app)

6% 34/570

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 に振り分けます。