50
43

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaScript複雑度の閾値チェック

Last updated at Posted at 2018-05-18

背景

JavaScriptコードのメトリクス測定がしたい。

JSでコードメトリクスといえば、Platoという優秀なビジュアライズツールがある。

しかし、それすら見に行かなくてもいいようにしたい。

具体的には、複雑度が閾値を超えるコードがpushされてきたら、CIが警告してくれるようにしたい。

使用するパッケージ

complexity-report

complexity-reportとは

CLIで複雑度計測。オプションで閾値チェックが可能。

インストール

npm install complexity-report --save-dev

実行

node ./node_modules/complexity-report/src/index.js <JSディレクトリまでのパス>

Platoとの併用

結論から言うと問題ない。

レポート生成と閾値チェックは異なるパッケージを用いることになってしまう。

とはいえ、Platoとcomplexity-reportはどちらも複雑度の計算にexcomplexというモジュールを利用しており、結果の整合性は問題ないはず。

依存関係をざっくり描くと以下の通り。

image.png

バージョンは以下のようになっている。

$ npm list --depth=0
...
├── complexity-report@2.0.0-alpha
...
├── plato@1.7.0
...

監視する複雑度

Cyclomatic Complexity(循環的複雑度)

概要

if, forなど条件分岐がどれだけあるかによって計算される

参考リンク

下限

0

上限

なし

閾値

こちらを参考に、メソッド毎に10を超えないようにした。
image.png

Maintainability Index

参考リンク

下限

0

上限

100

※ただし、この値はマイクロソフトが0から100に正規化した計算式を利用した場合のレンジであり、元の計算式はマイナス無限大から171までの数値で表される。
※Platoは正規化した式でMaintainabilityを算出している。complexity-reportはどちらの式を使用するかオプションで選択できる。

概要

保守性。

SLOC(ステップ数)、Cyclomatic Complexity、Halstead Volume(後述)から算出される総合的な保守性。

Visual Studioではこれを利用して保守性を判断してくれる。その際の基準値は以下の通り。

image.png

あるいは http://www.ecs.csun.edu/~rlingard/comp589/ColemanPaper.pdf の論文では38〜49(原著では正規化前の値で65から85)となっている。

閾値

ファイル毎に50を超えないようにした。

監視しなかった複雑度

Halstead Difficulty

参考リンク

下限

0

上限

なし

概要

難易度。

学習コストや実装コストの観点から算出される値。演算子や変数の種類と総数から計算される。

いくつ以上が何というものではなく、閾値の基準設定が難しかったので採用を見送った。

実際使用しているコマンド

$ node ./node_modules/complexity-report/src/index.js -n -C 10 -M 50 <JSディレクトリまでのパス>

オプションの説明

-n, --newmi                           use the Microsoft-variant maintainability index (scale of 0 to 100)
-M, --minmi <maintainability index>   specify the per-module maintainability index threshold
-C, --maxcyc <cyclomatic complexity>  specify the per-function cyclomatic complexity threshold

Platoはnewmiを使っているので、数値を合わせたい場合はnオプションが必要。

CI連携

今回の目的。

コードは省略。

CircleCIで上記のコマンドを叩いてやれば、閾値判定でジョブを成功させたり失敗させたりできる。

実際の運用

  1. push時にCIのコンテナが上記のコマンドを叩く
  2. 成功/失敗の判定をSlackやGitHubに通知
  3. 失敗したら成功するようにリファクタリングする

まとめ

JSコードメトリクスの閾値チェック

  • complexity-reportのインストール
  • CIジョブ追加: push時に実行
  • 失敗条件: Cyclomatic Complexityが11を超える関数またはMaintainability Indexが50を下回るファイルが検出された場合

JSのコードメトリクスのビジュアライズ

  • Platoを使用
  • CIジョブ追加: masterマージ時にレポートを生成

今回は、ES5コードで使用しているけれど、全く同じ手順でES6でも使用できるはず。

50
43
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
43

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?