| 目次 |
|---|
ユニットテストは「やったほうがいい」と分かっているのに、いつも後回しにしてしまう作業でした。正直、同じような作業の繰り返しで時間もかかるし、新機能を作るときほどワクワクしない。だからこそ、つい手が止まってしまうことが多かったんです。
でも、ある時から状況が変わりました。
SNSでよく見る「AIがアプリを1から作ってくれる」みたいな使い方ではなく、もっと現実的で、日々の開発で本当に役立つ形でAIを取り入れたのがきっかけです。
AIを“テストを書く相棒”として使うようになってから、Djangoのユニットテストの書き方が大きく変わりました。結果として、テストが「苦痛」ではなく「これなら無理なくできる」と思える作業になったんです。
この記事では、私が実際に経験したことをベースに、失敗したこと、そこから学んだこと、そして最終的にたどり着いた“無理なく運用できる”テスト作成のワークフローをまとめます。ユニットテストが毎回しんどいと感じているエンジニアのヒントになれば嬉しいです。
Djangoアプリのテストは「現実」と向き合う作業
Djangoをある程度触ってきた人なら分かると思いますが、Djangoアプリはすぐに複雑になりがちです。
- 複雑に関連し合うモデル
- 権限ルールを含むViewSet
- ネストしたバリデーションを持つSerializer
- コンテキスト次第で挙動が変わるFilter backend
- ユーザーによって返す内容が変わるエンドポイント
こういう要素が揃っていると、ただ python manage.py test を回すだけでは不十分です。
本当に必要なのは「本番に出る前にバグを止められる」レベルの、意味のある網羅的なテストです。
私の場合は、画面管理(screen management)の機能を作っていました。
画面には グローバル画面 / ワークスペース画面 / ユーザー画面 の3種類があり、並び順のロジックは Django の Case/When を使った条件分岐で実装していました。さらに、ユーザーの役割によって権限も変わります。
つまり「ロジックが複雑」「権限も複雑」という最悪の組み合わせです。
この状況では、テストは“あると便利”なものではなく、“ないと危ない”ものと言えます。
最初のAI活用:見事に失敗
AIを使ってユニットテストを書こうとした、私の最初の挑戦。
そのとき私が入力したプロンプトは、こんな感じでした。
「ScreenViewSetのユニットテストを書いて」
するとAIが出してきたのは、まさに“モンスター級”のテストファイル。
- テストメソッドが15個以上
- モックだらけ
- 使わないfixtureが大量に出てくる
- チームの書き方と合わないテストパターン
- 現実には起きないようなエッジケースまで網羅しようとする
- そして、コードベースに対する謎の前提や決めつけ
ファイルは巨大で、読みにくくて、混乱する内容でした。正直、修正する手間を考えたら「最初から自分で書いたほうが早い」レベル。
じゃあ、なぜこうなったのか?
理由はシンプルで、私がAIに“何も渡していなかった”からです。
- 参考になるテスト例なし
- 期待する構成の指定なし
- 守ってほしいルールもなし
つまり、「AIが判断するための材料」がまったくない状態でした。
だからAIは、こちらのテスト方針や慣習を知るはずもなく、勝手に「それっぽい」スタイルを作り上げてしまったんです。
転機:例を渡すプロンプトへの改善
2回目の挑戦は、最初とはまったく違いました。
AIに「とにかくテストを書いて」と丸投げするのをやめて、代わりに次のものを渡したんです。
- 実際に運用しているテストファイル(コードベース内の本物)
- チームで統一しているテストの構成・型
- 新しく作るテストで、何をカバーしたいかの具体的な要件
- チームでいつも使っている書き方・パターン
そして、AIにはこう伝えました。
「ApplicationTemplateViewSetTest の構成に合わせて、ScreenViewSet のテストを作って」
すると、反応が一気に変わりました。
AIが急に“こちらの流儀”を理解し始めたんです。
- テストクラスの組み立て方
- 普段どんなfixtureを用意しているか
- テストクライアントの認証方法
- 命名規則(テスト名・メソッド名)
- assertNumQueries の使い方
- 権限によるフィルタリングのテストの書き方
結果として、最初みたいなカオスなテストファイルではなく、
読みやすくて整理された、ほぼそのまま使えるレベルのテストが返ってきました。
実際に運用できるワークフロー
いろいろ試した結果、私が安定して良い結果を出せるプロセスはこれでした。
Step 1:コードベースから“例になるテスト”を選ぶ
ここで選ぶのは、いわゆる公式テンプレではありません。
チームがすでに「この形がいいよね」と思っている、実在のテストファイルです。これがあなたのテンプレートになります。
ViewSetをテストするなら、既存のViewSetテストを選ぶ
Modelをテストするなら、既存のModelテストを選ぶ
AIは、見せた例の書き方・構造・流れをそのまま真似します。まずは“真似してほしい型”を渡すのがポイントです。
Step 2:情報が揃った、具体的なプロンプトを書く
悪いプロンプト例はこんな感じです。
「Xのテストを書いて」
一方で、良いプロンプトはこうです。
「ApplicationTemplateViewSetTest と同じ構成で ScreenViewSet のテストを書いて。
list / detail / create / update / delete をカバーして。
特に、スコープの並び順(global → workspace → user)と権限によるフィルタリングを重点的にテストして。」
違いが伝わると思います。
この書き方だと、AIに次の情報をちゃんと渡せます。
- 何を作ってほしいか
- 何が重要か
- どんな構成にしてほしいか
- どの例を参考にしてほしいか
Step 3:レビューして、ピンポイントで修正させる
AIの最初の出力は、だいたい 70〜90% は合っています。
でも、最後は必ず人間が確認しないと危ないです。
チェックするポイントは例えばこんな感じ。
- 本当にテストすべき挙動を見ているか?
- チームの書き方・命名規則・流れに合っているか?
- 抜けているエッジケースはないか?
- fixtureが重すぎないか?
そして、必要があれば「ここだけ直して」と具体的に指示してAIに更新させます。
全部作り直させるより、部分的に直させたほうが早くて安定します。
私がやりがちだった失敗とそれを避けるコツ
1. AIが書いたテストを読まずに信じてしまう
これは一度やりました。もう二度とやりません。
テストは「通った」だけでは安心できません。パスしていても、実は何も検証していないことがあります。
2. 何でもかんでもモックにしてしまう
AIはパターンを知らないと、必要以上にモックを増やしがちです。
結果として、テストが“現実”から離れて、壊れやすくなります。
3. 重くて遅いfixtureを許してしまう
ガイドなしで任せると、AIはオブジェクトを大量に作ってしまいます。
そうするとテストが遅くなり、メンテもしんどくなります。
4. ドメイン特有のエッジケースを忘れる
AIは、こちらが伝えたことしか知りません。
プロダクトに固有のルール(例:権限、並び順、例外条件など)があるなら、プロンプトに最初から書くのが大事です。
実際にどれくらい時間が短縮できたか
AIを使う前は、テストファイル1本を書くのにだいたいこれくらいかかっていました。
AI導入前
- 何をテストすべきか整理する:30分
- fixtureの準備:45分
- テストを書く:2時間
- デバッグ:45分
- 合計:約4時間/1ファイル
ところが、AIに“良い例”を渡して、プロンプトをちゃんと設計するようになってからはこう変わりました。
AI + 良い例あり
- 参考になる既存テストを探す:5分
- プロンプトを書く:10分
- AIに生成させる:2分
- レビュー&微調整:30分
- デバッグ:15分
- 合計:約1時間/1ファイル
結果として、品質を落とさずに作業時間を約75%削減できました。
それでもAIが苦手な領域はある
もちろん、AIは万能ではありません。特に次のようなケースは、まだ苦手だと感じています。
- かなり複雑な業務ルールが絡むテスト
- セキュリティ観点のテスト
- パフォーマンスが重要なケース(ボトルネックになりやすい箇所など
- 複数サービスをまたぐ統合テスト(マルチサービスの連携)
こういう領域でもAIは補助にはなります。
ただし最終的には、こちらが仕様を理解して、意図を整理して、手で考える工程が必須です。
今のAIテスト作成ワークフロー
今の私は、だいたい次の流れでテストを書いています。
- 何をテストすべきかを整理する
- 似ている既存のテストファイルを1〜2本探す
- 具体的で情報量のあるプロンプトを書く
- AIにテストを生成させる
- 出力を全部レビューする
- 必要なら改善点を細かくAIに依頼する
- 実行して、落ちたところを直す
- コミットして次へ進む
この手順が固まってから、ほとんどのテストファイルは 45〜60分 くらいで仕上がるようになりました。
最後に
AIの力を借りながら、テストファイルを何十本も書いてきて分かったことがあります。
うまくいくケース
- 実際のテスト例(コードベースの本物)をAIに渡す
- 情報が揃った、具体的なプロンプトを書く
- 生成し直すより、改善を重ねて仕上げる(イテレーションする)
- 退屈で反復的な部分はAIに任せる
- でも、最終判断は自分が握る(自分が運転席にいる)
うまくいかないケース
- ふわっとした指示(曖昧なプロンプト)
- 「AIならこのドメイン分かるでしょ」と期待する
- コードレビューを飛ばす
- AIが勝手にチームのルールに合わせてくれると思い込む
- テストの基本原則を学ばないまま、AIに頼り切る
未来は、「AIがすべてのコードを書く」世界ではありません。
これから主流になるのは、AIが開発を加速してくれて、品質の舵(かじ)は自分で握り続けるという形です。
テストを1ファイル4時間かけていたのが、1時間で高品質に書けるようになると、テストに対する心理的ハードルが一気に下がります。
テストが一定のパターンで揃うほど、保守もしやすくなる。
AIが繰り返し作業を引き受けてくれる分、自分は「本当に大事なロジック」に集中できます。
良いテストには、やっぱり考える力が必要です。
ただ、AIをうまく使えば、そのプロセスはもっとスムーズに、もっと速く、そして正直…ちょっと楽しくなります。