はじめに
この記事では、ソフトウェアの品質をどう上げていくかについて、私が実務で強いと感じている考え方を整理します。
結論はシンプルです。
全体を一気に保証しようとするより、「ここは確実に正しい」と言える領域を少しずつ広げていく方が、結果として品質は安定します。
この考え方の背景には、ソフトウェア開発が本質的に不確実な営みだという前提があります。
Steve McConnell の『ソフトウェア見積り 人月の暗黙知を解き明かす』で整理されている「不確実性のコーン」は、この感覚を非常にうまく言語化しています。
この記事では、その不確実性の考え方を見積もりだけでなく、品質の上げ方にもつなげて考えます。
最初から全体を保証するのは難しい
ソフトウェア開発の序盤では、次のようなものがまだ固まっていません。
- 要件の解像度
- 例外ケースの扱い
- 外部依存の制約
- 既存コードの癖
- 運用上の前提
この状態で「システム全体として正しい」と言い切るのは難しいです。
そもそも、何をもって正しいとするかがまだ揺れています。
それなのに、最初から大きな粒度で品質を保証しようとすると、次のようなことが起きます。
- 通しテストを増やしすぎる
- 手動確認に頼りすぎる
- 広い範囲を一度にレビューしようとする
- 「たぶん大丈夫」という判断が増える
これでは、確認しているつもりでも、確実な領域が増えていきません。
不確実性のコーンは品質の話にもつながる
『ソフトウェア見積り』で有名な考え方の1つに、不確実性のコーンがあります。
これは、開発の初期ほど見積もりのぶれ幅が大きく、進むにつれて徐々に狭まっていく、という考え方です。
よくある説明では、プロジェクト初期の見積もりは、実際の工数に対しておおむね 0.25倍〜4倍 程度の幅を持ちうるとされます。
数字は文脈で多少変わりますが、重要なのは倍率そのものではありません。
重要なのは次の点です。
- 初期は分からないことが多い
- 進めることで分かることが増える
- 不確実性は観測と分解によって減る
これは品質の話でも同じです。
開発初期に「全体品質」を語っても、そこにはまだ未確認の前提が大量に含まれています。
一方で、処理を分解して小さな単位で検証すると、「ここは確実」と言える部分が増えます。
つまり、品質を上げるとは、不確実性をゼロにすることではなく、不確実な領域を少しずつ減らしていくことです。
品質は「確実な領域」の総和に近い
私が普段感じているのは、ソフトウェア全体の品質は、個々の部分でどれだけ「ここは確実」と言えるかに強く依存する、ということです。
例えば次のような状態を考えます。
- この判定関数は境界値までテスト済み
- このSQLは代表ケースと異常系を実DBで確認済み
- この変換処理は入力パターンを固定できている
- この外部API呼び出しは失敗時の扱いまで決めている
こういう点が増えるほど、システム全体の振る舞いも読めるようになります。
逆に、全体として動いているように見えても、細部が次の状態なら危ういです。
- 条件分岐の根拠が曖昧
- 例外時の挙動を誰も説明できない
- なぜその値になるのかテストで固定されていない
- 共有ロジックを変えたときの影響範囲が読めない
この状態では、見た目の動作確認が通っていても、品質は高いと言いにくいです。
「確実な領域」を広げる具体的な方法
考え方だけでは使いにくいので、実務でどう進めるかを整理します。
純粋関数に寄せる
まず効果が大きいのは、業務ルールを副作用から切り離すことです。
- 判定
- 集計
- 変換
- バリデーション
- 文面生成
こうした処理を純粋関数に寄せると、入力と出力で確実性を作れます。
ここはテストしやすく、変更にも強いです。
「この条件ならこの結果になる」が積み上がるので、確実な領域を増やしやすくなります。
DBや外部依存は役割を絞って確認する
次に、DBや外部APIのような結合部分です。
ここは純粋関数ほど軽くはありませんが、見るべき点を絞れば十分強い確認ができます。
- SQL条件は正しいか
- JOINや集計結果は合っているか
- 制約違反時に崩れないか
- 外部API失敗時にリトライや中断が正しいか
つまり、「何を保証するテストか」を明確にして結合テストを書く、ということです。
全体確認は最後に薄く置く
全体を通す確認も必要です。
ただし、ここで細部まで保証しようとすると、重くて曖昧な確認になりやすいです。
全体確認の役割は、次の程度に絞る方が安定します。
- 配線がつながっているか
- 主要フローが最後まで流れるか
- 最低限の代表ケースが成立するか
細かい業務ルールまでここに背負わせない方が、品質保証の構造は健全になります。
見積もりでも品質でも、大きすぎる単位は不確実
ここで見積もりの話に戻ります。
『ソフトウェア見積り』が示しているのは、初期の大きな見積もりほど不確実だということです。
これは品質確認にもそのまま当てはまります。
大きすぎる単位には、次の問題があります。
- 前提が多すぎる
- 失敗時の原因が分かりにくい
- どこまで確認できたかが曖昧になる
逆に、小さく分けると次のことが起きます。
- 前提が減る
- 期待値を明示しやすい
- 壊れた場所を特定しやすい
- 再確認コストが下がる
見積もりを細かく分けると精度が上がりやすいのと同じで、品質確認も小さな単位へ分ける方が強くなります。
「全部は分からない」を前提にした方が強い
実務では、「最初から全部分かる前提」の方がむしろ危険です。
分からないことがあるなら、次のように振る舞う方が強いです。
- 先に確実にできる部分を固める
- 仕様が揺れやすい場所は局所化する
- 影響範囲が大きい共通処理は先にテストで固定する
- 後で見直す前提で分割と観測を入れる
この進め方は地味です。
ですが、品質を安定させるのは、たいていこういう地味な積み上げです。
よくある誤解
最初から全体テストを厚くすれば安心ではないか
安心感はありますが、それだけでは確実な領域が増えにくいです。
通しテストは失敗理由が広すぎて、学習効率が低くなりやすいからです。
細かく分けると全体最適を見失わないか
そのリスクはあります。
だからこそ、局所テストだけで終わらず、最後に薄い全体確認を置きます。
局所で確実性を作り、全体で配線を確認する役割分担が重要です。
これは見積もりの話であって品質の話ではないのでは
むしろ逆です。
見積もりで見えている不確実性は、そのまま品質確認の難しさにもつながっています。
最初から全部は見えない、だから分解して観測可能にする、という考え方は共通です。
まとめ
ソフトウェア品質を上げるうえで重要なのは、最初から全体を保証しようとしすぎないことです。
開発の初期には不確実性が大きく、見積もりも品質判断もぶれやすいです。
不確実性のコーンが示しているのは、その現実を受け入れた上で、進むにつれて精度を上げていくべきだということです。
品質も同じです。
一気に「全部大丈夫」に近づくのではなく、「ここは確実」と言える領域を少しずつ増やしていく。
その積み上げが、結果として全体品質を押し上げます。
純粋関数、結合テスト、全体確認を役割分担しながら、確実な領域を広げていく。
この進め方は派手ではありませんが、長く運用できる品質向上のやり方だと思います。
参考