循環的複雑度の計測

背景

テストコードもない複雑なレガシーコードに対して変更する場合、常にデグレードのリスクが伴います。エンジニアの知見や経験によってそれを回避することも可能ですが、チームとして取り組む上では仕組みでそのリスクを軽減する必要があります。

以前、チームでレガシーコードに対して修正したとき、PR でレビューしたにも関わらず、デグレードが発生しました。原因を分析していくと、対象のメソッドは変更前から循環的複雑度が50を超えており、変更後はさらに数値が上がっていましたが、そのことをチームとして認識できていない状況でした。その他にも因子はありましたが、実装中からバグの混入確率を減らすことが期待できる仕組みの1つとして循環的複雑度に着目しました。

実際にバグ分析からプロセスを改善したときの方針と内容を以下に記載します。

方針

内部品質が低下することにより、バグの混入確率が上昇するため、内部品質を定量的に評価できる指標の1つとして循環的複雑度を用いる。 変更したコード、新しく追加したコードに対してバグの混入確率を循環的複雑度で評価し、定量的な指標をもとに適切に対処する仕組みを構築する。

循環的複雑度が低いことは内部品質が高いことの必要条件である。しかし、必要十分条件ではないことを留意する

期待する効果

循環的複雑度を把握することにより、現在より以下の効果(=バグの混入確率低下)を期待する

  • レビュイー自身がレビュー前に循環的複雑度が高いコードであることを認識することにより、事前に循環的複雑度を下げるためのリファクタリング単体テストとして網羅率が十分であるか確認できる
  • レビュアーが循環的複雑度が高いコードであることを認識することにより、循環的複雑度を下げるための内部設計として改善の余地がないか、バグが混入していることを前提としたコードの確認ができる

改善するプロセス

今後、循環的複雑度を把握し、バグの混入確率を下げるための取り組みとして以下を実施する。

  • Pull Request 時に修正前後のメソッド、新規のメソッドに対して循環的複雑度を計測する
  • Merge する条件に循環的複雑度を追加する
    • 修正前が30未満の場合、修正後が30以上の場合は NG とする (修正後が30未満であれば前回より増加しても需要する)
    • 修正前が30以上の場合、修正後が前回を超える場合は理由を記載する
      • x.x.x 以降は NG とする
  • 新規が30以上の場合は NG とする