関数のシグネチャ(名前・引数)だけ用意し、中身が空・最小限・NotImplementedError のままになっている未完成コード。「後で実装する」前提で一時的に置かれるが、放置されると気づかれないまま残り続ける。
概要
スタブ実装は次のような形で現れる。
def calculate_tax(amount):
raise NotImplementedError("未実装:税額計算ロジックはまだない")
def send_notification(user):
print("未実装:通知送信")
# 本来はメール/Slack送信処理が入るはず
呼び出されるまでは正常に見え、テストも通ってしまうことが多い。エラーログに埋もれて誰にも気づかれないまま本番まで残ることがあり、「静かな負債」と呼ばれる典型パターンの一つ。
テストダブルの Stub との違い
同じ「スタブ」という言葉でも、指しているものが異なる。
| スタブ実装 | テストダブル の Stub | |
|---|---|---|
| 目的 | 本実装を後回しにするための仮置き | テスト対象を依存先から切り離すための決め打ち値 |
| 置かれる場所 | 本番コード(未完成のまま) | テストコード(意図的・恒久的) |
| あるべき姿 | いずれ本実装に置き換わる | テストである限り存在し続けてよい |
| 放置した場合の問題 | 本番で機能が動かない「静かな負債」 | 特に問題にならない(設計通り) |
同じ語でも「本番コードの仮置き」か「テストの決め打ち値」かで意味が正反対に近い点に注意。
AI 駆動開発で増えやすい理由
LLM は「動くコード」を素早く生成する一方、範囲外の分岐やエッジケースに対しては NotImplementedError やコメントで済ませて先に進みがちで、スタブが量産されやすい。世代交代のたびに新旧のスタブが併存し、実態調査をしないと総数が把握できない状態になりやすい。
検出・一掃の考え方
NotImplementedErrorや「未実装」コメントを grep で機械的に洗い出す(複数行にまたがる呼び出しやコメント内の誤検出に注意)- 一度きりの手直しではなく、CI やレビューゲートで継続的に検出する仕組みにする
- 見つかったスタブは「本実装する」か「不要なら削除する」のどちらかで必ずクローズし、放置しない
関連記事
- Python ジョブ群編 — スタブ・enum 三重定義の一掃【実践編 第8章】 — NotImplementedError スタブの二世代併存を実態調査で一掃した実録