こんにちはー!むちょこです。
ご無沙汰しております。
AIエディタを使って開発するのが当たり前になってきたこの時代、使いこなす人とそうでない人の開発スピードにぐんぐん差がついているのを感じます……。
この記事では、現時点で私が最速と思っている「AIを最大限活用したテストコードの開発手順」を共有してみます。ルールファイルの作成からレビューまで、実務目線でなるべく再現性高くまとめました。
「もっと良い方法があるよ!」と思った方は、ぜひcommew(@むちょこ)やX(@muchoco_dev)でメンションいただけたら嬉しいです…!
ちなみに私は普段Cursorを使っています。
目次
1. 2つのルールファイルを作成
ルールファイルとは、AIエージェントに指示を与える設定ファイルのことです。
ルールファイルを最初に用意しておくと、AIエージェントがこのルールに従いながらコードを生成してくれるようになり、大幅な時間短縮と精度向上が見込めます。
Cursorの場合は設定ページの Rules & Memories から追加可能です。

php-rule.mdc
このファイルには、PHP全体のルールを記載します。
私は「以下の共通ルール + (必要があれば)プロジェクトごとのルール」という構成にしていることが多いです。
- 環境(PHPやフレームワークのバージョン情報)
- コーディングスタイル
- 非推奨関数
---
description: "PHP 用のルール"
globs: ["*.php"]
alwaysApply: true
---
# PHP コード規約
本ドキュメントは、 PHP を記述する際に守るべきルールを定義したものです。
---
## 📘 目次
1. [環境](#1-環境)
2. [コーディングスタイル](#2-コーディングスタイル)
3. [非推奨関数](#3-非推奨関数)
---
## 1. 環境
PHP 7.4
## 2. コーディングスタイル
### ✅ Rule: 優先順位
#### Description
コーディングスタイルのルールは、次の順で優先する。
1. プロジェクトで定められているルール
2. フレームワークで定められているルール
3. PSR-2 で定められているルール
## 3. 非推奨関数
原則として、将来非推奨になることが確定している関数は使用を控えてください(やむを得ない場合を除く)。
### ✅ Rule: 2038年問題を避けるための日時処理
#### Description
`strtotime()` や `mktime()` は、内部で32bit整数の Unix タイムスタンプを使う可能性があり、2038年1月19日以降の日時に対して誤動作を起こすことがある。
そのため、日時の処理には常に `DateTime` クラスを使用する。
#### 禁止事項
- `strtotime()` の使用
- `mktime()` の使用
#### 推奨手法
- `DateTime` クラスのインスタンスを用いた日時生成
- `DateTime::createFromFormat()` を用いた安全なパース
- `DateTime::getTimestamp()` を用いたUnixタイムスタンプの取得
#### Examples
**Bad**
```php
$timestamp = strtotime("2040-01-01");
$timestamp = mktime(0, 0, 0, 1, 1, 2040);
```
**Good**
```php
$date = new DateTime("2040-01-01");
$timestamp = $date->getTimestamp();
```
```php
$date = DateTime::createFromFormat("Y-m-d", "2040-01-01");
```
### ✅ Rule: インラインコメントには「処理の内容」ではなく「意図」を書く
#### Description
- コードが何をしているかではなく、「なぜその処理が必要なのか(意図)」を書く
- コードとコメントの乖離を防ぐためにも、「意図」ベースの記述を心がける
#### Example
**Bad(処理内容)**
```php
// 配列をソートする
usort($items, $sortFunc);
```
**Good(意図)**
```php
// 表示順は管理画面の仕様に従う
usort($items, $sortFunc);
```
#### Reason
- コードの背景や文脈が伝わる
- 将来の保守・変更時の判断に役立つ
- コメントとコードの不一致による誤解を減らす
phpunit-rule.mdc
このファイルには、テストコードに関するルールを記載します。
長くなるので内容は省略しますが、私の目次はこんな感じです。
## 📘 目次
1. [環境](#1-環境)
2. [ディレクトリ構造](#2-ディレクトリ構造)
3. [命名規則](#3-命名規則)
4. [コーディングスタイル](#4-コーディングスタイル)
5. [アサーションの書き方](#5-アサーションの書き方)
6. [テストデータの扱い方](#6-テストデータの扱い方)
7. [その他ベストプラクティス](#8-その他ベストプラクティス)
このルールをどれだけ作り込むかによって生成されるコードの品質に大きく影響するので、気になるところ・明文化できることがあればどんどん書き込むようにしています。
2. AIエージェントに開発を依頼
テスト対象のファイルを指定して、テストコードの作成を依頼します。

ルールを設定しても、初めのうちは何故か結構無視されていました。
コード生成の依頼時にルールファイルを引用して「phpunit-rule.mdcに従ってください」と添えたり、コード生成後に「phpunit.mdcの命名規則に従って修正してください」などと修正依頼を出しているうちにだんだんと覚えてくれたように思います。
3. 全体のテスト実行
AIエージェントがコードを生成してくれたら、とりあえずそのファイルのテストをすべて実行します。

このとき失敗するテストケースも多いかと思いますが、ポイントは「複数のテストケースが同じ原因で失敗していないか」という点です。
4. 広範囲に影響するエラーを潰す
いくつかのテストケースが同じ原因で失敗している場合(共通部分に原因がある場合)は、このタイミングで先に修正しておきます。
私がよく遭遇するエラーの原因としては、このようなものがあります。
- 依存クラスを正しく呼びだせていない
- 前提条件(初期化処理など)が省略されている
5. テストケースごとの確認と調整
初期段階で失敗していた共通の原因を解消したあとは、テスト対象のコードと照らし合わせながらテストケースを1つずつ確認していきます。

テストが成功しているとつい安心してしまいそうになりますが、どのテストケースも油断せず丁寧に目を通しておくことが大切です。
また、テストケースを確認するときには次のような点に注目して確認します。
- コメントに書かれている検証内容が適切か
- コメントの内容と実装されたテストコードが一致しているか
- 使用しているデータやファイルの扱いが正しく、安全か
- テストが正常に通るか
- テストが他のテストに依存したり、影響を与えることがないか
特に、失敗しているテストの修正をAIに依頼するとコメントの内容と実装されたテストコードがズレていくことがあるので注意が必要です。
6. 全体のテストケース実行
個別のテストケースを一通り修正し終えたら、改めてそのテストファイル全体のテストを実行します。
「修正漏れがないか」や「他のテストに干渉されて失敗するテストがないか」をチェックするのが目的です。
7. レビュー
仕上げに、AIエージェントにレビューを依頼します。

これまではステップ6までで完了としていたのですが、どうしてもAIエージェントが生成した”それっぽい”コードや抜け漏れていたテストケースを見逃してしまうことが度々ありました。
そこで、AI自身にも客観的なレビューをしてもらう工程を追加し、改善が必要な点がないか洗い出してもらうことにしました。挙げられた改善点に対して対応の要否を判断し、必要があれば修正→テスト実行→レビューの流れを繰り返します。
8. 最後に
以上が、私が普段実践している手順です。
テスト対象クラスのボリュームにもよりますが、この流れで大体1クラスあたり15分~1時間(中央値は30分前後)ほどで実装ができています。
より良い方法が見つかったら、この記事も随時更新していきたいと思います。
ご覧いただきありがとうございました🙌