もしかしたらコードメトリクスこそが、僕たちを救ってくれるかもしれない。

## 結論

* コードメトリクスの一つ、**保守容易性指数**と、**バグ発生率**とに、相関の兆候を見つけた
* まだ下調べの段階だけど、大規模調査および統計的検定の結果、  
**保守容易性指数**と**バグ発生率**との相関が認められたら、  
保守容易性指数をKPIにすることで、数値的品質評価・管理ができるかもしれない
* バグをまき散らすけど手が早いエンジニアの影に隠れて、  
丁寧にモノづくりをしているけどいまいち評価されていないエンジニアに、  
日の目をあてられるかもしれない。
* バグ対処コストと保守容易性とを掛け合わせることで、  
技術的負債を金銭的評価ができる可能性がある
    * 金銭的に評価できれば、返済に関して、ビジネスサイドと有意義な議論ができる可能性がある

## はじめに

僕ら(@gakuri、@ahera、@yukke7624)は、とあるSI会社で横断的にプロジェクト支援をしている。
マネジメント状況の監査、支援、テコ入れから、技術的アドバイザリ、ソースコードレビューまで。

ソースコードレビューでは、全体としての「良い」「悪い」は指摘するし、
修正すべきコードも個別に修正案を提示する。

ただ、この「良い」「悪い」は主観である。主観は信用できない。
定性評価であり、「かなり良い」「そこそこ良い」など
ざっくりした評価とならざるを得ず精密さに欠ける。

そもそもレビューは極めて労働集約的であるし、アナログだ。
そもそも顧客のデジタルトランスフォーメーションを支援する会社なのに、
自分たちはとってもアナログでしたというのは笑えない冗談だ。

なんとかプロジェクトを・ソースコードを、定性評価ではなく定量評価できないだろうか？
という問題意識を抱えて業務を遂行していた。

## Googleの先行事例

Googleは自動テストの結果が不安定（Flaky）なモジュールに調査したところ、
「3人以上がファイル変更している」ことを発見したらしい。
https://speakerdeck.com/nihonbuson/flakytests?slide=20

1人よりも2人が変更しているほうが、不具合が多いのは当然として、
1人⇒2人、3人⇒4人の時と比べて、2人⇒3人の時に、
一気にリスクが上がると[JaSST Tokyo 2018](http://jasst.jp/symposium/jasst18tokyo/details.html#A1)で言っていた（気がする）

このように、コードに関する何らかの数値とバグとの相関を見つけることで、
これまで以上に、もっと賢く開発ができるのではないだろうか？と考えた。
GitのAPIやソースから機械的に出した数値で、リスク評価できるなら、
多数の案件を網羅的にリスク評価でき、限りある人的資源を効率的に投入できるのではないかと。

## 仮説および下調べ

まずは、アイデアベースで仮説を立て、
少数の開発プロジェクトをピックアップし、手計算で筋がよさそうか確認した。

### 仮説1. Googleの変更者数の知見が、自分たちのプロジェクトでも当てはまる

否定。

特にその兆候は見られなかった。
そもそも3人が修正しているファイルが、設定ファイル以外にほとんどなかった。
自分たちのプロジェクトは自社パッケージに個社カスタマイズするプロジェクトであるため、
共通部分をみんなして修正することもなく、
また、慣例により画面別に担当を分解してアサインすることが多いためと考えられる。

なお、少数事例の3人以上修正でも、特に不具合が起きやすかったという傾向はなかった。

### 仮説2. コミット行数が平均を大きく上回った日にバグが混入しやすい

否定。

これも特にその兆候は見られなかった。
コミット数が少なくてもバグは起きるし、多くても起きない場合があった。
人別に分解してみたりしたが、やっぱり相関がみられなかった。

行数が急に増えた、安定しているからと言って、バグの埋め込まれ方に影響はでない。

というか今考えれば、仮説として筋が悪すぎる

### 仮説3 ～ 7

否定されたし、仮説としての筋も悪いので割愛

### 仮説8. サイクロマティック複雑度が高いとバグが混入しやすい

不明。

サイクロマティック複雑度は、VisualStudioなどIDEで計算できるコードメトリクス。
パッと見、相関はないように見受けられた中、仮説9. 保守容易性指数がきれいな相関を見せたため、
詳細な調査は打ち切った。

一つ明確なのは、SQL文の誤りが原因のバグは自社においては、
比較的ポピュラーである一方、サイクロマティック複雑度は、
SQL文の複雑度は評価できないという原理上の不可能性がある。

従って、Modelと、Modelを除いた部分とで層別し分析すれば、
相関関係が見えるかもしれない。
あるいはLOGICとVIEWで分けることで、さらに相関はきれいになる可能性がある。

### 仮説9. 保守容易性が低いとバグが混入しやすい。

強く相関が疑われる。

以下は、全関数について保守容易性を計算し、
そのうちバグが混入した関数の比率を表したヒストグラムである。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138414/bd392994-1334-a3d7-7047-0603312c2ba9.png)
これを見るとどの案件でも60を下回るとバグが出始め、
40を超えると、ちょっと無視できないくらいリスクが上がってくる。

## 保守容易性指数 と リスク評価構想

### 保守容易性指数とは

Microsoftが開発した（？）コードメトリクス指標。

* 算術演算子や論理演算子などから計算されるハルステッド複雑度の自然対数
* 循環的複雑度
* 関数行数の自然対数

をもとに計算される指標。
[詳しくはこちら](https://docs.microsoft.com/ja-jp/archive/blogs/codeanalysis/maintainability-index-range-and-meaning)

なぜこの指標が保守容易性を示すのか、経験則なのか計算機学の理論が背景にあるのか、
正直まったくわかりませんが、すくなくとも自社の少数の案件のバグに強い相関が疑われた。

### 現時点での課題

上記のグラフは、きれいではあるが「相関がある」と称するのは早計である。
上記の手法は統計的手法だが、母集団が少なすぎてただの偶然の可能性が排除できていない。
相関係数も出ていないし、検定も行われていない。
いずれにしてももう少し標本数が必要だし、
時期の違い、組織の違い、開発内容の違いなど、
標本の無作為性を導入しないと、普遍性を獲得できない。

### リスク評価構想

しかしながら、この相関が統計上の検定を突破できれば、
保守容易性区分ごとのバグ率予測が成り立ち、
出来上がったソースコードから、将来のバグ数が予測できることになる。

また、バグフィックスコストが経験的に算出できれば、
将来どれだけコストが予定されるか計算できることになる。

この将来に積みあがったコストとは、技術的負債の一部である。
任意のシステムについて、10人月分の負債が積みあがっているのか、
それとも100人月分の負債が積みあがっているのか、
計算可能であることを意味する。
※技術的負債とは、関数レベルのものもあれば、クラスレベル、
※アーキテクチャレベルのものもあるので、
※技術的負債すべてをこれで表現できるわけではない。

金銭的に評価できるということは、ビジネスサイドと返済について、
同じ土俵で会話できることになる。

手が早いか遅いかで不当な評価を得ていた、きちんと書くエンジニアが、
ビジネスサイドから正当な評価を得ることにもつながるし、
保守容易性指数で評価されるようになれば、
きちんと書こうとするエンジニアも増えるだろう。

## 今後の展望

現在、データ数を増やすため、@ahera と @yukke7624 が、
データ取得のシステム化、Jenkinsによる自動取得化を進めている。

実際のところ、ソースコードから保守容易性を自動で取得してくるのは、
複数システムによる連携とそこそこステップ数があり、
これ自体相当な開発を行っているのだが、
詳細については、@ahera、@yukke7624 に投稿してもらおうと思っている。

今後、自社内で相関が証明できたら、他社の開発でも通用するのか、
共同研究を募っていきたいと思う。