AIコードレビューを「指摘」から「テスト」に変える
AIの指摘は、そのまま不具合の証明にはなりません。コードレビューを実務で使うなら、まず期待する動作を固定し、指摘ごとに失敗を再現するテストを作ります。本稿は小さなPython関数を保守する開発者向けに、仕様の読み違いと本当のバグを切り分け、修正前後を自分の環境で確かめる手順を示します。モデルの評価点ではなく、実行結果を判断材料にします。
要点
- 最初に「何が正しいか」を文章と具体例で固定します。
- 指摘には入力、期待値、実際の結果を添えてもらいます。
- テストを実行するのは手元の開発環境です。チャット内のコード表示は実行結果ではありません。
レビュー前に関数の契約を決める
例として、品目数と単価から小計を返す関数を考えます。数量は0以上の整数、単価は0以上の整数で、単位は円とします。小数の数量、負数、真偽値は受け付けません。「入力を適当に数値に変換する」のか「不正な型を拒否する」のかを決めないままレビューを頼むと、モデルは別の仕様を正解として提案してしまいます。
この例には、消費税、割引、通貨換算を含めません。それらを勝手に追加する提案は改善ではなく仕様変更です。依存ライブラリーのバージョン、呼び出し元で保証される条件、公開APIか内部関数かも書き添えます。判断できない条件は、コードを直す前に確認事項として残します。
「危険そう」を再現可能な指摘に変える
Pythonではboolがintのサブクラスなので、isinstance(value, int)だけで検証するとTrueが整数として通る場合があります。今回の契約では真偽値を拒否するため、ここが実際の確認点になります。一方、仕様が真偽値を許可している別の関数なら、同じコードを直す理由にはなりません。
モデルには、重大度だけでなく、最小入力、期待する結果、その根拠、失敗するテストを求めます。さらに「実行していないテストを、成功したと書かない」と指定します。行番号は参考情報にとどめ、どの条件分岐で契約に反するかを説明してもらうと、差分が変わっても指摘を追いやすくなります。
レビュー対象の仕様:
- 数量と単価は0以上の整数。boolは拒否する。
- 不正な型はTypeError、負数はValueError。
- 税、割引、外部通信は追加しない。
各指摘を次の順番で出してください。
1. 再現する最小入力
2. 仕様に基づく期待値または例外
3. 現行コードで起こる動作
4. 修正前に失敗するunittest
5. その指摘だけを直す最小差分
未実行のものは未実行と明記してください。先に失敗を確認するテストを書く
次のテストは、正常系、ゼロ、負数、真偽値、文字列を分けて確認します。subtotal.pyに対象関数、test_subtotal.pyにテストを置き、python -m unittest -vで実行します。boolを通してしまう実装なら、そのケースが修正前に失敗することを実際に確認してください。
テストの期待値をレビュー対象の関数で計算すると、同じ誤りを共有してしまいます。3個、単価120円なら360円という独立した小さな例を使います。大きなランダム入力を大量に試す前に、何の間違いを検出するテストなのかを一文で言える状態にします。
import unittest
from subtotal import subtotal
class SubtotalTests(unittest.TestCase):
def test_three_items(self):
self.assertEqual(subtotal(3, 120), 360)
def test_zero_quantity(self):
self.assertEqual(subtotal(0, 120), 0)
def test_negative_quantity(self):
with self.assertRaises(ValueError):
subtotal(-1, 120)
def test_invalid_types(self):
for value in (True, False, "3", 3.0, None):
with self.subTest(value=value):
with self.assertRaises(TypeError):
subtotal(value, 120)
with self.assertRaises(TypeError):
subtotal(3, value)
if __name__ == "__main__":
unittest.main()最小修正と既存テストを照合する
この契約ではtype(value) is intを使えば、boolや整数サブクラスを含めて除外できます。ただし、整数サブクラスを許可する必要があるシステムなら、この選択は適しません。モデルの修正案を採用する前に、型の扱いが本当に呼び出し元と一致しているかを確認します。
修正は一度に一つの論点へ絞ります。例外の型を変えるなら、それを受け取る呼び出し元も確認します。追加したテストが通った後、プロジェクトの既存テスト一式を実行し、別の仕様を壊していないかを見ます。新しい一件の成功だけで「全体を検証済み」とは判断できません。
def subtotal(quantity, unit_yen):
if type(quantity) is not int or type(unit_yen) is not int:
raise TypeError("integer values required")
if quantity < 0 or unit_yen < 0:
raise ValueError("non-negative values required")
return quantity * unit_yen渡すコードの範囲と実行の境界を分ける
最初は対象関数、仕様、関連する呼び出し元、現在の失敗ログに絞ります。巨大なリポジトリー全体を貼るより、例外処理や入力保証が見える範囲を選ぶ方が、指摘の前提を確認しやすくなります。秘密鍵や本番認証情報はレビューに不要です。
Dikayaのブラウザーチャットではコードを表示、コピー、ダウンロードできますが、その表示がコードの実行を意味するわけではありません。有料チャットでファイルを添付する場合も、対応形式と容量制限があります。テストは自分の開発環境で実行し、実際のコマンド、終了状態、出力をレビュー記録に残します。
レビュー完了の条件を短い記録にする
採用した指摘ごとに「契約」「再現入力」「修正前の失敗」「修正後の成功」「既存テストの結果」を残します。再現できなかった提案は、未確認または設計上の相談として分離します。不要なリファクタリングを同じ差分に混ぜないと、あとから原因を追いやすくなります。
AIコードレビューの目的は、指摘の数を増やすことではありません。少数でも再現できる問題を見つけ、必要な変更だけを取り込み、次回も同じ不具合を検出できる状態にします。まずは一つの関数でこの流れを作り、確認可能な範囲を少しずつ広げてください。
よくある質問
AIが「テストは通ります」と書いたら検証済みですか?
いいえ。実際の実行環境、コマンド、終了状態、出力がなければ、それは予測です。ブラウザーチャットのコードブロックは実行結果ではありません。手元で修正前の失敗と修正後の成功を確かめ、既存テストも実行します。
レビューで見つかった提案はすべて直すべきですか?
仕様違反、保守上の提案、単なる好みを分けてください。入力と期待値で再現できる問題を先に扱い、仕様変更を伴う案は別に検討します。指摘の重大度だけで採用せず、呼び出し元への影響も確認します。
この整数検証を金額処理にそのまま使えますか?
この例は円単位の整数小計という限定された契約です。小数、税、丸め、複数通貨、返金を扱う実際の会計処理を網羅しません。必要な単位と丸め規則を先に決め、その契約に合わせて別のテストを用意してください。
出典
AIの支援を受けて作成した記事です。例は説明用であり、実際のモデル回答や比較試験の記録ではありません。外部資料はサービスの利用条件に代わるものではありません。
- Python公式:unittest
docs.python.org - Python公式:boolと数値型
docs.python.org
この課題をチャットへ
質問の下書きだけを移します。送信操作をするまでリクエストは送られません。新しい生成にはアカウントの利用条件が適用されます。
この課題をチャットへ ドキュメント