メインコンテンツへスキップ
AIが書いたコード、ほんとに大丈夫?(テスト)
レッスン 2 / 10|16分で読めます

AIが書いたコード、ほんとに大丈夫?(テスト)

動いてるように見えても、中でバグってるかも。特に薬用量とか、間違うと命に関わる系は絶対テスト。

このレッスンで終わる頃には

  • AIが書いたコードを確信を持って使える状態になる
  • テストの書き方をClaudeに任せつつ、最終確認は自分でやる型が身につく
  • TDD(テスト駆動開発)の基本が分かる

このレッスンで作るもの


動いてるように見えても、大丈夫?

Claudeに請求書計算アプリを作らせたとする。動いた。ボタンも効く。見た目もちゃんとしてる。

でも、計算は本当に合ってる?

単価1000円の商品を15個受注したとする。計算機が 15000円 を返せば正解。150000円 を返してきたら10倍の過大請求。

画面見てるだけじゃ分からない。これが業務アプリの怖いところです。

答えはテスト。「このインプットならこのアウトプットが返るはず」を自動で確認する仕組み。


テストって何?

ざっくり言うと、「こうなるはず」のリストを別ファイルで書いておく。実行すると、合ってたら緑、間違ってたら赤。

BMI計算器ならこんなリスト:

  • 身長170cm・体重70kg → 24.2が返るはず
  • 身長0cm → エラーになるはず
  • 体重マイナス → エラーになるはず

これをコードで書く。ボタン1つで全部チェックできる状態になる。

テストの色: 緑=期待通り、赤=期待値とずれている、を信号機で示した図
テストランナーは交通信号と同じ。緑は進んでOK、赤は止まれ

やってみる: BMI計算器+テスト

Claudeにこう頼む:

Claude Code
$

BMI計算器をTypeScriptで作って。身長(cm)と体重(kg)を渡してBMIを返す関数。テストも一緒に書いて。エッジケースも含めて。

本体とテストの2ファイルができる。テストはこんな感じ:

import { calculateBMI } from "./bmi";

test("普通の入力", () => {
  expect(calculateBMI(170, 70)).toBeCloseTo(24.22, 1);
});

test("身長0はエラー", () => {
  expect(() => calculateBMI(0, 70)).toThrow();
});

test("体重マイナスはエラー", () => {
  expect(() => calculateBMI(170, -5)).toThrow();
});

読めなくていい。英語部分がさっき日本語で書いた「はず」のリストと同じことをやってる。

実行

Terminal
$npx vitest run
✓ src/bmi.test.ts (3)
✓ 普通の入力
✓ 身長0はエラー
✓ 体重マイナスはエラー
Test Files 1 passed (1)
Tests 3 passed (3)

全部緑ならOK。計算は信頼できる。

テストファイルを確認して、node --test で実行する。全部 pass なら、この計算は少なくとも書いた条件では信頼できる
ターミナルで BMI 計算のテストが2件 pass している画面
緑の結果は「期待した入力と出力が一致した」という意味。数字を扱う業務では、この確認を目で見るのが大事

赤くなったら?(わざとバグ入れてみる)

Claude Code
$

BMI計算で、わざと割り算を間違えて。それからテストを走らせて。

赤くなる:

Terminal
FAIL src/bmi.test.ts
✗ 普通の入力
Expected: 24.22
Received: 2422.15
差分: 100倍

期待値と実際の値が両方出る。100倍のズレが一目で分かる。

テストが無かったら、このバグに気づかないまま使い続けてた可能性がある。


Claudeへの頼み方、3パターン

3つ目、業務アプリでは必須。バグは普通のケースより、変な入力(体重0、身長9999、文字列)で出る。


「テスト先に書く」という選択肢(TDD)

ちょっと上級。テストを先に書いて、テストが通るようにコードを書くやり方もある。TDD(テスト駆動開発)と呼ばれる。

TDD考案者のKent Beckは、AIエージェントと組み合わせたときのTDDを強く評価しています。

VoicesBLOG / NEWSLETTER

Test driven development (TDD) is a 'superpower' when working with AI agents.

筆者訳

テスト駆動開発(TDD)は、AIエージェントと働くときに『スーパーパワー』になる。

Kent BeckTDD考案者・アジャイルソフトウェア開発宣言共同著者The Pragmatic Engineer(Gergely Oroszによるインタビュー)2025年6月11日newsletter.pragmaticengineer.com/p/tdd-ai-agents-and-coding-with-kent

ただし同じインタビューで、注意も促しています。エージェントに任せると、コードを直すのではなくテストそのものを削除して通そうとする挙動に手を焼くことがある、と述べたとされています。テストの数が減っていないか、diffを見て確認してください。

Claudeへの頼み方:

Claude Code
$得意先向けの請求書計算、まずテストだけ書いて。
$条件:
$- 単価1000円×数量15個 → 15000円が返る
$- 数量0以下 → エラー
$- 上限金額を超えたら警告
$
$

テストを書いて、赤になることを確認。その後、テストが通るように実装して。

先に「こうなってほしい」を決めてから作る。仕様書代わりにもなるのがメリット。

注意

数字を扱う業務アプリではテストが必須

計算ミス、単位の取り違え、ゼロ除算。これらの数字がそのまま顧客や取引先に届くのはまずい。

AIに任せっきりにしないで、テストを書かせた上で、結果を自分の目で確認する。ここだけは譲れない。

テストのコード自体はClaudeに任せていい。大事なのは「テストがある」「結果を見た」の2つです。


テストを「確実に」させる4段階

「テストも書いて」と頼むだけでは、確認の強さが足りない場面もあります。公式ドキュメントは、検証の強制力を4段階に分けています。

VoicesDOCUMENTATION

Give Claude a check it can run: tests, a build, a screenshot to compare. It's the difference between a session you watch and one you walk away from.

筆者訳

Claudeに、自分で走らせられる確認手段を渡すこと。テストや、ビルドや、比較用のスクリーンショット。それが、付きっきりで見ているセッションと、席を外していいセッションの違いになる。

Claude Code公式ドキュメントBest practicescode.claude.com/docscode.claude.com/docs/en/best-practices

段階が上がるほど、強制力も上がります。

1つ目は、プロンプトの中で検証と修正を頼むこと。ここまでは、この章で扱ってきた「テストも書いて」がそのまま当てはまります。

2つ目は、セッション全体の条件として設定すること。「テストが全部通るまで終わらない」という条件を、そのセッションの目標として渡す段です。

3つ目は、Stop hookでスクリプトを強制すること。Claudeが「終わった」と言っても、決められたスクリプトが通らなければ止められます。ただし、同じ理由で8回連続ブロックすると、Claude Code側がその制止を上書きしてしまう仕組みもあります。強制にも限界があると覚えておいてください。

4つ目は、第三者による検証です。フレッシュなコンテキストで動く別のサブエージェントに、これまでの作業で見つけたことを検証し直させる段です。実装した本人がそのまま確認すると、見落としをそのまま見落としがちです。

頼み方の具体性も、この強さに直結します。

Before: 「テストを書いて」とだけ頼む After: 「validateEmail関数を書いて。テストケース例: user@example.comはtrue、invalidはfalse。実装後にテストを実行して」

期待値まで渡すと、Claudeが自分で答え合わせをできます。任せる範囲は広くても、確認の基準はこちらが決める。


テストフレームワーク、どれを使う?

迷ったらVitest(TS/JS)/ pytest(Python)。Claudeに「テスト書いて」と頼めば、これらで書いてくれる。

Vitest 公式ドキュメント Getting Started ページのスクリーンショット
Vitest 公式ドキュメント。Claudeに「テスト書いて」と頼むと、このGetting Startedの構成に沿って書いてくれる
SourceARTICLE
Vitest 公式ドキュメント

高速で書き味の良いテストランナー。ClaudeがTS/JSでテスト書く時の標準。

Webvitest.dev
vitest.dev/guide
SourceARTICLE
pytest 公式ドキュメント

Pythonの定番テストランナー。業務システムのスクリプトを書くなら必須。

Webdocs.pytest.org
docs.pytest.org
SourceARTICLE
TDD: Test-Driven Development(Martin Fowler)

TDDの考え方を簡潔に解説。なぜテストを先に書くのかが分かる原典。

記事martinfowler.com
martinfowler.com/bliki/TestDrivenDevelopment.html

習慣にすると楽

新しい機能を頼むたびに「テストも書いて」と一言添える。それだけで、AIが書いたコードの信頼度が跳ね上がる。

テストがあると、後から修正するのが怖くなくなる。変更→テスト実行→全部緑なら他の機能は壊れてない、と確認できる。

テストが無いコードは、逆に何を直すたびに「他は大丈夫?」って目視確認する羽目になる。未来の自分への保険、と思って書かせる。


まとめ

  • 動いてるように見えても、計算が合ってるかは別問題
  • テスト = 「こうなるはず」の自動チェック
  • Claudeに「テストも書いて、エッジケースも含めて」と頼むのが基本
  • 業務アプリでは必須。結果は自分の目で確認
  • 「テスト先に書く」TDDも選択肢
  • 確実にしたいときは、プロンプト→/goal→Stop hook→第三者検証の順で強くできる

次はマルチエージェント。複数のClaudeを同時に走らせる話。


明日のアクション

入門編で作ったアプリ、または新しいプロジェクトで、何か1つ計算系の関数をClaudeに作ってもらってください。

「テストもエッジケースを含めて書いて」を忘れず添える。

テスト実行して、全部緑になることを自分の目で確認。このサイクルを1回通すと、「あー、こういう感じか」が分かります。