結論
サイクロマティック複雑度(CCN)を監視することは、モジュールが「テスト可能か?」を測る有効な指標になる。次点の効用として、保守が困難なモジュールの可視化や、リファクタリングすべきかどうかの判断基準にも使える。
まとめ
- CCN監視は単なるソースコードサイズ削減だけでなく、テスト設計工数と相関がある
- CCNを監視することで「そのモジュールは現実的な工数でテストできるのか?」を見極められる
- Jenkinsとlizardを使えば、自動計測と通知は簡単に仕組み化できる
- 結果として、プロジェクトの品質保証に「腹落ちする理由」を持ってCCNを導入できた
背景
最初にCCN計測を導入したのは、とある母体ソースコードの関数が巨大で、保守が非常に困難だったからだ。
解決のために、ソースコードがpushされるたびにJenkinsが検知してlizardを通し、CCNを計測。基準値を超えていたら関係者へメール通知する仕組みを作った。
すると、モジュールのサイズは劇的に小さくなった。機械的な基準に基づいて自動判定してくれる仕組みは、自分に非常に合っていた。
他プロジェクトへの展開と「大義名分探し」
この成功体験から、他プロジェクトにも展開を考えた。しかし展開するためには「大義名分」が必要だと考えた。
結果的には誰も拒否反応を示さず受け入れられたのだが、当時は理由を明文化したかった。
最初に考えたのは「モジュールを小さくできる」ことだった。しかしこれは既存の大規模モジュールに手を加えるほどの動機には弱いと感じた。
そこで、CCNの算出式 との睨めっこが始まった。
CCNの簡易算出式
$$
CCN = 1 + \text{(if, while, for, case などの分岐数)}
$$
この式を見つめ直していたときは、なかなか「自分なりの答え」が出なかった。
答えにたどり着いたきっかけ
答えが見えたのは、モジュール単体テストの導入時だった。
既存の巨大モジュールにテストを書いていたとき、ふと気づいた。
「CCNはC2カバレッジを満たすために必要なテストケース数と相関があるのでは?」
分岐や繰り返しの数で求められるCCNは、確かに必要なテストケース数に直結していた。
この発見が、私にとって「CCNを監視する腹落ちする理由」になった。
CCNと「テスタブルか?」という問い
私は「モジュールが現実的で、かつコストに見合う工数でテスト可能であるか?」を テスタブル(testable)か? と表現した。
CCNは、その問いに答える指標になった。
結果的に、もともと誰も反対していなかったが、この説明は受け入れられ、納得感を持って展開できた。
次点の効用
CCN監視の効用は「テスタブルか?」を測ることが第一だが、次のような副次的な効果もある:
- 保守が困難なモジュールを可視化し、放置されないようにできる
- CCN基準値オーバーをリファクタリング判断のトリガーにできる
イメージ図
テストケース数とCCNの相関イメージ
テストケース数
^
| *
| *
| *
| *
+-----------------> CCN
まとめ
- CCNは単なるコードサイズの話ではなく、テスト可能性と密接に関係している
- 「CCNを監視する理由」は、腹落ちする形で説明できる
- Jenkins + lizard で自動化すれば、導入コストは低い
- 次点の効用として、保守が困難なモジュールの可視化やリファクタリング基準にもなる