Datadog が Claude + Cursor で挑むテスト駆動型の本番マイグレーション:使い回せる一連の方法論

·Toolin 編集部

TDD を新規コード開発から大規模レガシーリファクタリングへ拡張し、まず AI で振る舞いの契約を固定してからテストをセーフティネットにする。Datadog の 3 フェーズ・エンジニアリング実践を解説します。

Datadog が Claude + Cursor で挑むテスト駆動型の本番マイグレーション:使い回せる一連の方法論

大規模なレガシーコードのマイグレーションは、どのエンジニアチームも恐れるタスクです。関数を 1 つ触れば回帰テストが大量に落ち、触れなければ技術的負債が積み上がる一方。AI ツールは確かにコード修正を速めてくれますが、「壊れたコードを作る作業」も同じ速さで加速します。セーフティネットのない AI リファクタリングは、ひとたび外れると大惨事です。

Datadog のエンジニアリングチームが最近、そのまま真似したくなる実践を公開しました。Claude + Cursor による「テスト駆動型」の本番環境マイグレーションです。核心は、TDD(テスト駆動開発)を「新規コードを書く」から「大規模なレガシーコードのマイグレーション」へ拡張し、AI の力で先に振る舞いの契約を固定してから、テストをセーフティネットとして使うことです。

本記事では Datadog の 3 フェーズ手法を分解し、自分のコードベースに再適用できるワークフローを示します。

手法の全体像:意図 → テスト → マイグレーション

Datadog の手法は 3 ステップに分かれており、各ステップで AI ツールを使いながらも、人間が常に重要な節目でチェックを入れます:

フェーズ目的ツール
1. 意図の記述「この関数は何をすべきか」を書き下すClaude
2. 絞り込んだテストの作成既存の振る舞いをテストケースとして固定する人間 + Claude
3. マイグレーションの実行テストの保護のもとでリファクタリングするCursor

この順序の鍵は、テストを先に用意してからコードを動かすこと。従来の「先にマイグレーション、後からテストを追加」とは正反対です。

ステップ 1:Claude で意図を記述する

マイグレーションで最も問題が起きやすいのは「コードを間違えて変更した」ことではなく、「コードは正しく直ったのに、振る舞いが変わった」ことです。あなたがバグだと思い込んでいたエッジケースが、実は上流モジュールが依存している契約だった——という落とし穴はよくあります。

だからこそ、コードに一切手を入れる前に、重要な関数ごとに振る舞いの意図を書き留めます:

  • この関数の入力は何であるべきか?
  • 何を返すべきか?
  • 必ず保持しなければならないエッジケースはどれか?
  • 副作用(ログの書き込み、外部 API の呼び出し、グローバル状態の変更)はどれか?

この作業には Claude を活用できます。プロンプトはおおむね次のようになります:

以下は、まもなくマイグレーションする関数のソースコードです:

```python
def normalize_event(raw):
    ...

このコードに基づいて、「振る舞いの意図ドキュメント」を書いてください:

  1. この関数の中心的な責務は何か
  2. 入力パラメータの型、範囲、制約
  3. 出力の型、構造、制約
  4. コードから識別できるすべての副作用とエッジケース
  5. 「バグに見えるが、実際には依存されている契約」である振る舞いはどれか

説明のみを出力し、コードは変更しないでください。


> 💡 **ヒント**:Claude に 5 点目を意識させることが極めて重要です。レガシーコードには「バグに見える」振る舞いが数多くありますが、実際にはどこかの上流モジュールが依存しています。変更すれば事故になります。

出力は自然言語で書かれた「振る舞いの契約」になり、次のステップでテストを書く際の根拠となります。

## ステップ 2:絞り込んだテストを書く

意図ドキュメントができれば、狙いを定めたテストを書けます。このステップは**人間 + AI の共同作業**です:

- 人間:どの振る舞いを固定するかを決める(どれがコアの契約で、どれがエッジケースか)
- AI:意図ドキュメントに基づいてテストケースのコードを素早く生成する

テストの目標は「カバレッジ 100%」ではなく、**重要な振る舞いを固定すること**です。とりわけ、マイグレーションの過程で最も壊れやすい振る舞いを重点的に守ります。

Claude でテストのドラフトを生成します:

```text
以下の振る舞いの意図ドキュメントに基づいて、この関数の狙いを定めた pytest テストケースを生成してください:

[ステップ 1 の意図ドキュメントを貼り付け]

要件:
1. 「コア契約」の振る舞いをすべてカバーし、少なくとも 2 つのテストケースを用意する
2. 「エッジケース」の振る舞いをすべてカバーし、それぞれ少なくとも 1 ケースを用意する
3. 「バグに見えるが実際には依存されている」振る舞いをすべてカバーし、それぞれ 1 ケースにコメントを付ける
4. ケースはマイグレーションの前後どちらでも通ること(特定の実装には依存せず、振る舞いのみに依存する)

このテストのドラフトを人間がレビューし、AI が思い至らなかった境界条件を補い、冗長なケースを削除します。

💡 ヒント:このステップでテストを「釘付け」にしてください。マイグレーション開始後、これらのテストはセーフティネットです。どんな変更でもテストを落としたら、立ち止まって「テストが古くなったのか、コードが本当に壊れたのか」を確認しなければなりません。

ステップ 3:Cursor でマイグレーションを実行する

テストが整えば、思い切ってマイグレーションに取りかかれます。ここで Cursor の出番です。コードベースのコンテキストを扱う能力は、大規模リファクタリングにとても向いています。

作業のリズム:

  1. 小刻みに移行する:一度に移すのは 1 モジュールか、関連する関数のグループだけ。一括の大変更はしない
  2. テストを回す:小さな変更のたびに即座にテストスイートを実行する
  3. レッド/グリーンの循環:テストが落ちたら → コードかテストを直す → 全部緑になったら → 次の周回へ
  4. 人が diff をレビューする:Cursor が生成したマイグレーションコードは、必ず人がレビューしてからマージする

Cursor では、次のような形でマイグレーションを指示できます:

@Context: マイグレーション対象のモジュールを選択
@Files: 関連するテストファイルを参照

@normalize_event を旧イベント形式から新しい v2 形式へ移行してください。
要件:
1. テスト [ファイル名を貼り付け] がすべてパスし続けていること
2. 振る舞いの意図ドキュメントに記述されたすべての契約を維持すること
3. 変更を diff 形式で出力し、変更箇所ごとに理由を注記すること
4. テストがカバーしていない曖昧な振る舞いに遭遇したら、自分で決めずに立ち止まって聞くこと

鍵となる設計は 4 番目——AI に、不確実な場面では立ち止まって人に聞かせることです。自分で決め込ませない。これこそが、テスト駆動型マイグレーションで品質を守れる根本の理由です。

本番のオブザーバビリティを IDE に取り込む

マイグレーション完了後の最大のリスクは「テストは全部通ったのに、本番で落ちた」というパターンです。テストではカバーしきれない振る舞い——実際のトラフィックパターンや実際のデータ分布に依存する問題——が存在するからです。

ここに、Datadog のこの実践の特に賢い部分があります。Datadog は Cursor(および VS Code)向けの IDE 拡張を公式に提供しており、本番のオブザーバビリティデータ(telemetry、logpoint、error tracking)をエディタに直接取り込めます。

マイグレーション後に何かの関数が本番で問題を起こしても、Datadog の Web ページへ切り替えてログを漁る必要はありません。Cursor の中でその関数の実際のエラー率、遅いリクエストのサンプル、スタックトレースを直接確認できます。

💡 ヒント:Datadog ユーザーでなくても、この発想は応用できます。どんな形の本番オブザーバビリティ(Sentry、Grafana、自社開発 APM)でも IDE に取り込めば、「テスト + 本番データ」がそろってマイグレーション後のセーフティネットになります。

検証基準

一連のテスト駆動型マイグレーションが妥当だったかの判定は、次のようになるべきです:

  1. 絞り込んだテストが 100% パスしている
  2. 本番のメトリクス(エラー率、レイテンシ、QPS)がマイグレーション前後で有意に変化していない
  3. コードレビューに「振る舞いは変わったのか」という未決着の問題が 1 つも残っていない
  4. 意図ドキュメントが更新されている(新バージョンの振る舞いの契約は何か)

よくある質問

  • レガシーコードにそもそもテストがない場合は:まさにこの手法の最大の価値が発揮される場面です。AI にテストを「補ってもらう」のです。振る舞いの意図ドキュメントからテストを逆算する方が、コードから逆算するより信頼できます。
  • AI が生成したテスト自体が間違っていた場合は:人間のレビューが常に最後の関門です。AI にテストを生成させたら、少なくともコアのケースは人が一度実行して、本当に正しい対象を検証しているか確かめてください。
  • この手法は Datadog 規模のチームにしか向かないのか:いいえ。手法の本質は「先に振る舞いを固定し、それからコードを動かす」ことで、あらゆる規模のマイグレーションに適用できます。小さなプロジェクトなら Datadog 拡張を省き、Claude + Cursor + 一式のテストだけで十分です。

おわりに

Datadog のこの実践の肝は「Claude と Cursor を使った」ことではなく、TDD の考え方を「大規模リファクタリング」という新しいシナリオへ正しく持ち込んだことです。まず AI で振る舞いの契約を固定し、テストをセーフティネットにして、最後にその保護のもとで AI にコードを任せます。

公式のケース報道は InfoQ を参照: https://www.infoq.com/news/2026/07/datadog-ai-production-migration/

正直な注記:本記事は、Datadog のエンジニアリング実践に関する InfoQ の公開報道に基づいて執筆しました。移行対象のコード量や所要時間などの具体的な数字は、原文に正確な値がなく、本記事でも創作していません。「大規模・本番レベル」のエンジニアリング実践の事例としてのみ述べており、Datadog が発表した新製品ではありません。