【C/C++/C#/Java対応】循環的複雑度の計測ツール lizardの導入方法【Swift/Rust/GoもOK】

前書き:ネストの深さを指摘する時間が勿体無い 

コードレビューを効果的に実施したいと考えた事はありませんか?

例えば、短い期間でソフト開発する場合、レビュー時間を潤沢に取れないケースがあります。このような場合は、

  • 基本的なコーディング不備(ネストが深いなど)は、静的解析ツールで検出
  • ビジネスロジック不備は、ヒトがコードレビューで検出

と、レビュー目的に応じて作業分担した方が効果的です。しかし、静的解析ツールは数多くありますが、ライセンスが必要であったり、商用利用が難しい場合があります。

本記事では、MITライセンス(商用利用可能)でリリースされている「循環的複雑度の計測ツール lizard(Python製)」の概要、インストール方法、使用方法を紹介します。

                                    

検証環境

elementary OS5(Ubuntu派生)上で、lizard version 1.17.7およびPython 3.6.9を使用します。

                                     

lizardが提供する機能

lizardは、ソースコードの循環的複雑度(Cyclomatic Complexity Number)、メソッドの行数、メソッドのパラメータ数、ファイル内のメソッド数を算出します。任意の閾値を超えた場合、閾値以上のメソッドに警告を出せます。

静的解析結果は、標準出力、csvファイル、hmtlファイルに残せます。

                          

lizardの対応言語

A list of supported languages:

  • C/C++ (works with C++14)
  • Java
  • C# (C Sharp)
  • JavaScript (With ES6 and JSX)
  • TypeScript
  • Objective-C
  • Swift
  • Python
  • Ruby
  • TTCN-3
  • PHP
  • Scala
  • GDScript
  • Golang
  • Lua
  • Rust

—lizard READMEより–

                               

インストール方法

aptパッケージマネージャとpip3コマンドでインストールします。なお、lizardと一緒にインストールするjinja2は、lizardによる静的解析結果をHTMLに変換する際に使用するテンプレートエンジンです。

                                              

実行例と結果の読み方

lizardコマンドを実行すると、カレントディレクトリ以下のファイルに対して静的解析します。

以下の実行例では、JavaのCore APIを静的解析しています。各ファイル内のメソッド毎に循環的複雑度を算出した後、閾値を超えたメソッドに対して警告を出します。

                                               

上記の結果に登場する用語を下表で説明します。

用語 説明
CCN 循環的複雑度。if文、for文、switch-case文が増えると数値が上がります。0〜10は最良、11〜20はやや複雑、21〜40はテストしづらい、50以上は危険。
NLOC メソッドやファイルのコード行数(コメントを除く)
token トークンとはコンパイラが字句解析/構文解析する際の最小単位(要素)であり、ここでは関数中のトークン数です
PARAM メソッドのパラメータ数
length メソッドやファイルのコード行数(コメントを含む)

                                               

上表の中で、トークンという用語には馴染みがない方がいらっしゃるかもしれません。以下にトークンの例を示します。

For example: if (abc % 3 != 0) Has [‘if’, ‘(‘, ‘abc’, ‘%’, ‘3’, ‘!=‘, ‘0’, ‘)’] 8 tokens.

–lizard公式GitHubのIssue–

                                       

csvファイルの残し方

csvオプションとリダイレクトを使用します。どの列がどの結果かは出力されないので、不親切。

                             

HTMLファイルの残し方

htmlオプションとリダイレクトを使用します。

HTMLの表示例は、以下の通りです。閾値を超えている結果は、背景色が赤くなります。

                             

警告のみを出す場合

–warnings_only(w)オプションを使用します。

                    

警告閾値を変更する場合

デフォルトでは、以下の閾値設定がされています。正直、循環的複雑度を除いて、設定がテキトーすぎる印象です。

  • 循環的複雑度(CCN)> 15
  • メソッド行数 > 1000
  • ファイル行数 > 1000000
  • パラメータ個数 > 100

閾値の変更はThreshold(T)オプションで行います。

閾値を変更できるパラメータは、helpを読む限りnloc、cyclomatic_complexity、token_count、parameter_countと書かれています。メソッド行数(length)のみ、length(L)オプションで閾値変更します。

以下の例では、CCN>10、メソッド行数>100を閾値として設定しています。

                               

ホワイトリストの設定

「このメソッドは警告が出ても仕方がない」という場合は、テキストファイルに当該メソッド名を書く事で警告を抑止できます。

以下、書式です。カレントディレクトリにwhitelizard.txtを置かなくても、Wオプションでホワイトリストファイルパスを指定できます。

                                      

おまけ:利用を断念した静的解析ツール

基本的にはライセンス面(購入が必要)で断念しています。ただし、Understand、C++Test、Coverityは多機能であるため、「金銭コスト」と「解析時間の長さ」が気にならない人は採用を検討して良いかもしれません。

静的解析ツール 断念理由/個人的な印象
Understand ライセンス購入必須。ソースコードの構造を様々な方法で可視化する機能を持つ。個人的には、似た機能を持つSourcetrailの方が気軽に使いやすい。
C++Test ライセンス購入必須。単体テストのカバレッジ取得、コーディングルールチェック、フロー解析が強い。C/C++向けツールのため、組み込みソフト向け。
Coverity ライセンス購入必須。到達不可能なコード、推奨されないコーディング、不要な初期化など幅広い指摘を出す。C++Testに近い機能だが、Coverityは対応言語が多い(21個の言語対応)。
SourceMonitor 対応言語が若干少ない(C/C++/C#、VB.NET、Java、Delphi、VB、HTML)。商用のソフト開発に利用可能なライセンスであり、利用を断念する理由はあまり無い。ただ、公式サイトが古臭くて調査しなかった。
cppcheck ライセンスはGPLv3。C/C++向けであり、組み込みソフトであれば利用を検討した可能性あり。

                                                                                                

おすすめ

1件の返信

  1. 2021年5月22日

    […] 循環的複雑度を計測する静的解析ツール。複雑度やメソッドの長さに対して警告が出せるため、冗長なコードの検出に役立つ。使用方法の記事はコチラ。 […]