夕方のデスク。
新しく直したコードを実行したら、真っ赤なエラーメッセージが並ぶ。
「ここ、単体テストで拾えていれば…」とため息をついた経験はありませんか?
そんな場面を減らすために、今回は単体テストで必ず押さえておきたいポイントをまとめました。
単体テストの役割をあらためて整理
まずは基本の確認から。
- 単体テストは関数やクラスなど、最小単位のモジュールを対象に動作を確認するもの。
- 外部システムやデータベースは切り離し、対象そのものの正しさをチェックする。
- 結合テストやシステムテストと違って、依存関係はモックやスタブを使って代替する。
調査によると、単体テストで発見される不具合の割合は 約30%。
統合テストの35%に比べれば少し劣りますが、それでも早期に直せる効果は大きいと言われています。
押さえておきたいチェックリスト
私自身の経験も交えて「これは最低限やっておきたい」と思う項目をピックアップしました。
ベストプラクティスと実務での実感を混ぜています。
テスト設計・戦略
- カバレッジ目標を決める
指標がないと、テストが数合わせになりがち。多くの現場では 70~80% をひとつの目安にしています。 - 境界値や異常系を忘れない
空文字、NULL、例外、オーバーフローなどを必ず入れておく。 - 優先順位を付ける
全部を完璧に網羅するのは難しいので、重要な処理や影響の大きい部分から。 - テストしやすい設計を意識
依存を外から注入できるようにしておくとテストが組みやすくなります。
出典:せお丸のプログラマー養成講座
コーディング時の工夫
- AAAパターン(Arrange / Act / Assert)を守る
準備→実行→確認がはっきりして、読みやすいテストになる。 - テスト名は意味を持たせる
メソッド名_条件_期待結果のように書くと失敗時の原因がすぐ分かります。 - インフラ依存は持ち込まない
DBやファイルアクセスはモック化。そうしないとテストが重く、不安定になります。 - テストコードにロジックを書かない
複雑な処理は逆にテストのバグを生みやすい。 - 一つのテストで一つのケースだけを確認する
複数を混ぜると、失敗したときの切り分けが難しくなる。 - 同じ入力なら同じ結果を出すこと
乱数や時刻に依存する処理は制御しておく。 - 後片付きを忘れない
テスト同士の干渉を防ぐため、環境やモックはきちんとリセット。
実行と運用のポイント
- CIと連携させる
コミットごとにテストが走るようにして、早めに不具合を発見。 - スピードを大事にする
遅いテストは回さなくなるので、できるだけ軽く。 - 保守性を意識
コードが変わったらテストも変える。重複や不要なテストは整理。 - 失敗時のログをしっかり残す
入力や実行パスを記録しておけば、原因追跡がスムーズに。 - カバレッジ以外の指標も活用する
欠陥の流入経路、実行時間、失敗率なども見ておくとより実態が分かります。
出典:古賀正雄 エンジニアマインド
注意点
もちろん「単体テストさえやれば安心」というわけではありません。
- カバレッジが高くてもバグは残る
条件の組み合わせや設計上の問題までは拾えないことも。 - やりすぎはコストが増える
改善効果の少ない部分に大量のテストを書くと、保守の負担ばかり増える。 - カバレッジと品質の関係は弱い
研究では、テストカバレッジの高さと実際の品質の相関は低いとされる例もあります。 - AIや確率処理が入ると難易度が上がる
非決定的な挙動をどうテストするかは別の工夫が必要。実際、AI系OSSの多くは単体テストが十分に整っていません。
まとめ
単体テストは「基本だけど奥が深い」工程です。
カバレッジの目標を決める、異常系を入れる、依存を切る、CIとつなぐ…
一つ一つは小さな工夫でも、積み重ねることで安心感が違ってきます。
ただし万能ではありません。
結合テストやレビューと組み合わせてこそ、真の品質保証につながります。