◉CLAUDE LABEN
●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/Claude Code
⟐ Claude Code/2026-05-04中級

Claude Code でテストカバレッジを段階的に改善する

カバレッジが低いプロジェクトでClaude Codeを活用し、テストを段階的に増やすワークフローを解説します。カバレッジレポートの解析、未テスト関数の一括検出とテスト生成の依頼方法、TypeScriptとVitestでの実践手順、よく詰まるポイントと対処法までを具体例で示します。

claude-code132testing5vitesttypescript11test-coverage

テストカバレッジが40%を切ったとき、最初にすることは何でしょうか。手動でコードを眺めて「ここが怪しい」と感覚でテストを書き始める方が多いと思います。そのアプローチ自体は悪くないのですが、カバレッジレポートを読んでClaude Codeに何をテストすべきか指示できれば、作業時間を大幅に短縮できます。

実際に私が個人開発プロジェクトで試したところ、カバレッジが45%から78%まで上がるのに使ったのは実質2時間弱でした。もちろん生成されたテストをそのままコミットするのは危険なので検証は必要ですが、「どこから手をつけるか」という判断の負担がほぼゼロになりました。

テストカバレッジとは何を計測しているか

カバレッジと一口に言っても、ツールによって計測対象が異なります。Vitest(c8 / istanbul)では主に以下の4種類を報告します。

  • Statements: 実行された文の割合
  • Branches: if/switch等の分岐で両方のパスを通ったかの割合
  • Functions: 呼び出された関数の割合
  • Lines: 実行された行の割合

個人的にはBranchカバレッジが最も意味のある指標だと思っています。Functionカバレッジが100%でも、関数内の条件分岐が全てテストされているわけではないからです。エラーハンドリングのパスが抜けていたり、nullチェックが通過できていなかったりすることが多く、実際のバグの温床になりやすい部分です。

Vitestでカバレッジを有効にするには vitest.config.ts に以下を追加します。

// vitest.config.ts
import { defineConfig } from 'vitest/config'
 
export default defineConfig({
  test: {
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html'],
      // 対象ファイルを明示することで計測精度が上がる
      include: ['src/**/*.ts', 'src/**/*.tsx'],
      exclude: ['src/**/*.d.ts', 'src/**/index.ts'],
      // カバレッジが下限を下回ったらCIで失敗させる(任意)
      thresholds: {
        branches: 60,
        functions: 70,
      },
    },
  },
})

npx vitest run --coverage を実行すると coverage/ ディレクトリにHTMLレポートが生成され、ブラウザで開くと視覚的に確認できます。ただし、Claude Codeとの連携では coverage/coverage-summary.json の方が扱いやすいです。

Claude Code でカバレッジレポートを解析する

coverage-summary.json にはファイルごとの詳細カバレッジデータが格納されています。このJSONをClaude Codeに読ませることで、改善すべきファイルの優先度付けを任せることができます。

coverage/coverage-summary.json を読んで、
Branchカバレッジが60%未満のファイルを一覧化してください。
ファイルパス・現在のカバレッジ・未カバー分岐の推定箇所を
箇条書きで教えてください。

Claude Codeはこのプロンプトを受けて coverage-summary.json を読み込んだ上で、実際のソースコードを確認し、どの条件分岐がテストされていないかを推定して返してくれます。

この分析にかかる時間は概ね30秒程度です。手動でJSONを解析してソースと突き合わせる作業が消えるだけで、どれだけ楽になるか実感できると思います。また、Claude Codeはコードの文脈を理解した上で「このエラーパスはユーザー入力のバリデーション不足が原因になりやすい」といった付加情報も提供してくれることがあります。

未テスト関数を一括検出してテスト生成を依頼する

分析結果をもとに、テスト生成を依頼します。ポイントは「全部まとめて生成して」ではなく、ファイル単位で段階的に依頼することです。一度に多くのファイルを指定すると、後半の生成品質が落ちたり、既存テストとの整合性が取りにくくなったりします。

src/utils/pricing.ts のBranchカバレッジが42%と低いです。
このファイルを読んで、テストされていない条件分岐を特定し、
Vitestのテストケースを書いてください。

要件:
- 既存の __tests__/pricing.test.ts に追記する形で
- エッジケース(0円、負の値、通貨コードが不正なケース)を含める
- describe / it ブロックを使って整理する
- 期待値を明確に記載する(expect(result).toBe(true) のような曖昧なアサーションは避ける)

この要件の最後の一行が重要です。アサーションの質についての制約を入れると、生成されるテストの品質が目に見えて上がります。指定しないと「通過すれば何でもいい」という形骸化したテストになることがあります。

TypeScript + Vitest の実践ワークフロー

実際に私がプロジェクトで使っているワークフローをまとめます。

ステップ1: カバレッジを計測してJSONを出力

npx vitest run --coverage --reporter=json
# または
npx vitest --coverage

ステップ2: 低カバレッジファイルをClaude Codeに分析させる

coverage/coverage-summary.json を確認して、
Branchカバレッジが最も低いファイル上位5件と、
それぞれに対して「どんなテストを追加すれば改善するか」を
1ファイル2〜3点で簡潔に教えてください。

ステップ3: 重要度の高いファイルからテスト生成を依頼

優先度は「ビジネスロジック → エラーハンドリング → ユーティリティ」の順が効果的です。テストが実際のバグを防いだという経験が積み上がってきたら、徐々に周辺部分にも広げていくのが持続しやすいやり方です。

ステップ4: 生成されたテストを実行・レビュー

npx vitest run __tests__/pricing.test.ts

失敗するテストがあれば、エラーログをClaude Codeに渡して修正を依頼します。

このテストが失敗しています:
[エラーログをここにペースト]

原因を特定して修正してください。

ステップ5: カバレッジを再計測して改善を確認

この一連の流れを2〜3ファイルに繰り返すと、カバレッジの数値が動いているのが実感できます。数値の改善だけでなく、「テストを書く判断力」がClaude Codeとの対話を通して自分自身にも蓄積されていく感覚があります。

よく詰まるポイントと対処法

モックの設定が実際の型定義と合わない

外部依存(APIクライアント、DBアクセス)が絡むファイルでは、vi.mock() の設定が実際のインターフェースと食い違うことがあります。その場合は「このモックは型エラーになります。実際の型定義は〜です」と返してあげると修正してくれます。型定義ファイルのパスを一緒に渡すとより正確に対応できます。

カバレッジが上がっても品質が上がらないケース

テストが通過するだけで、実際の挙動を検証できていない「空テスト」になることがあります。expect(result).toBeTruthy() のような曖昧なアサーションが生成されたら、「このケースで具体的に何が返るべきか」をClaude Codeに聞き直してください。多くの場合、「〜が返るはずなので expect(result).toEqual(...) に変えるべき」と正確な答えが返ってきます。

既存テストとの命名衝突

同じ describe ブロック名や it 名が被ることがあります。追記前に既存テストの構成をClaude Codeに共有しておくと避けられます。cat __tests__/pricing.test.ts の出力を一緒に渡す習慣をつけると、このトラブルはほぼ発生しなくなります。

生成されたテストが遅い

非同期処理が絡むテストで、実際のAPIコールやDBアクセスが走ってしまうことがあります。「このテストはモックを使って実行時間を最小化してください」と追記するか、生成後に手動で vi.mock() を確認するのが確実です。

テストの詳細な自動化手法については、Vitest・Jest 単体テスト自動化ガイドやテスト駆動開発ワークフロー入門もあわせて参考にしてください。

全体を振り返って

今日すぐできることは一つです。プロジェクトで npx vitest run --coverage を実行して coverage/coverage-summary.json を生成し、Claude Codeに「Branchカバレッジが低いファイル上位3件と、それぞれの改善ポイントを教えて」と聞いてみてください。5分で現状把握が終わり、どこから手をつけるべきかが明確になります。

カバレッジ改善は「計測すること」からしか始まりません。計測コストが下がれば、改善する動機も自然と高まります。Claude Codeはその「計測→分析→テスト生成」のサイクルを大幅に短縮してくれます。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⟐ Claude Code2026-03-28
Claude Code × Playwright で E2E テストを本番運用に乗せる — 落とし穴と導入の判断基準
Claude Code と Playwright を組み合わせて E2E テストを本番運用するための実装パターンと、導入効果の測り方。Cloudflare Workers/Pages preview deployment 下での落とし穴と、個人開発者がテストを導入する判断基準まで踏み込んで解説します。
⟐ Claude Code2026-08-28
名前に混ざった見えない文字を、プラグインを入れる前に洗い出す小さなスクリプト
プラグインやスキルの名前に不可視文字や制御文字が混ざっていても、ターミナルの一覧では見分けがつきません。実際に6つの紛らわしい名前を並べて ls の出力を比べ、導入前に走らせる点検スクリプトと、その点検が拾えない範囲までを整理しました。
⟐ Claude Code2026-08-26
キャッシュのTTLを1時間に延ばすかは、離席の長さではなく戻る場所で決めています
Claude Code v2.1.242 で promptCacheTtl と subagentPromptCacheTtl が追加されました。1時間キャッシュが効く条件は離席時間ではなく、同じ作業ディレクトリと同じ git 状態へ戻るかどうかです。判断の順番と、効いているかを確かめる手順を書き残します。