オカルトから科学へ - SonarQubeで静的コード解析を始めよう

ちなみに、タイトルは半分釣りというか、個人に依存したオカルトから、誰がやっても同じになる科学的な方法論をもっと入れてこう、って意図です。

もちろん、そういった部分を全部なくすのでは無くうまく組み合わせるのが大事。魔術と科学が交わるときには何かが起こるのです!(これが言いたかっただけ)

なんで静的コード解析?

チームやプロジェクトでコードレビューをしていますか?

多くの開発プロセスではコードレビューまたはペアプロが実施されていると思います。しかし、人の目で見てるだけでは不十分であり非効率です。

人間によるレビューは経験や勘、あるいはレビューアの好みに依存してしまう部分があります。 そのため、違う人がやれば違う結果になることはしばしば有ります。

また、そういった自体を防ぐためにレビューチェックシートを使う場合もあるでしょう。その場合の多くは退屈な作業を人がやることになります。 数が増えれば増えるほどミスをする可能性も増えてきます。

そんな時に役立つのがFindBugsやPMD, StyleCopなどの静的コード解析ツールです。 これらをIDEやJenkinsなどのCI環境に入れることで、ツールによる差異はありますが概ね下記の点を見つけることが出来ます。

  • 命名規則やインデントなどのスタイルが適切か
  • 一般的にバグの原因になり易い危険なコードはないか
  • コードクローンなど品質の問題になりやすいコードはないか

という感じで色々と見つけてくれます。正直、この手のツールと同じ土俵で人間が勝負するのは無理です。精度で負けます。

なので、誰でも出来る部分は科学の産物たる機械にまかせて、人間にしか出来ない観点でレビューをするのがベストです。導入することで以下の効果が期待できます。

  • レビューアに依存しない定量的なレビュー
  • コード量やレビューアの忙しさに依存せずに素早く確実にレビュー結果を得られる

個人的にはサーバサイドにレポートが出せてグラフィカルに内容を共有出来るSonarQube(旧名Sonar)を使ってるので、その紹介と導入方法を共有したいと思います。

SonarQubeとは?

まずは、ざっくりしたSonarQubeの紹介です。

かつてはSonarと言われるものでFindbugなどJavaのコード解析ラッパーから始まったツールです。

f:id:pascal256:20140211132149j:plain

Pluginを利用することでC#PHP, JavaScriptAndroidなど多くの環境をサポートします。詳細は公式参照(Plugin Library - SonarQube - Codehaus)

Sonarの気に入ってるところとしては

  • グラフィカルで分かりやすいUI。複数のツールのメトリクスを集約して見れる
  • タイムラインでメトリクスの増減を見れる
  • 導入が簡単。また、個々の開発メンバーが導入する必要は無いので、負担が少ない
  • プラグインやRESTベースのAPIで拡張可能

があります。特にタイムラインで見れるので、コードメトリクスがどう変化していったかを追うことができるので、すでに運用しているコードにも適用しやすいのが便利でした。

Sonarのインストール

インストールはかなり簡単です。

wget http://dist.sonar.codehaus.org/sonarqube-4.1.1.zip
unzip ~/Downloads/sonarqube-4.1.1.zip
cd sonarqube-4.1.1/
./bin/macosx-universal-64/sonar.sh start

起動したら

http://localhost:9000/

にアクセス。これで完了。ね、簡単でしょ?

本格的に使うにはDBをMySQLに変えるとか、Apacheと連携させるとかすると良いと思いますけど、まずは動かすだけならこれで大丈夫。

Sonarの使い方

JavaMaven環境を作ってるならゴールをsonar:sonarにするだけです。ブランチ名の指定とかしたいので、普段は以下のようなオプションにしています。

これをJenkinsに登録するだけで、定期的にSonarのレポートが作られるようになります。

# デフォルト名
mvn sonar:sonar -D.sonar.forceAnalysis=true -Dsonar.host.url=http://localhost:9000/

# ブランチ名とか指定したいとき
mvn sonar:sonar -D.sonar.forceAnalysis=true -Dsonar.host.url=http://localhost:9000/ -Dsonar.branch=branch-name

Sonarを使った開発プロセス

やりかたは色いろあると思いますが、うちでは主に以下のようなやり方を実践しています。

  1. 開発開始時にmasterより開発ブランチを作成
  2. 各開発ブランチをJenkinsに登録しCI環境に登録毎時でブランチ専用のSonar画面を作成
  3. 開発メンバーは随時、Sonarの画面を確認。問題が上がれば修正
  4. 開発完了時にレビューアはSonarの指摘が無いことを確認した上で、レビューを行い開発メンバにFBする
  5. FBの修正及び再レビューが終われば、リリースブランチにマージ

開発の規模感としては並行して5から10案件程度は動いており、同じ数だけ開発ブランチがあります。これより大きい規模の開発だと、また違った方法論が必要な気がしますが、同程度以下ならある程度同じようなプロセスでいけると思います。

この運用でポイントとなるのは、3のSonarの画面を見て問題があれば修正する、という部分です。

まず、基本的なサイクルとしては指摘を見て修正すれば良いのですが、ルールベースで指摘しているという仕組み上の問題で、設計上は問題なかったりする指摘やら誤検知がそこそこがあります。

これをレビューアなど適切に判断出来る人にエスカレーションした上で、問題なしのチェック等を入れます。そうすると指摘上から消えるので、この部分の指摘は無視して良いとか人間が毎回判断する必要はありません。

残念ながらこの設定がブランチで共有出来ないので、現在は新規でブランチを作る度に手動でコピーしています。 この辺、良い方法があったら、ぜひ教えて下さい。

また、新規コードから適用してるなら指摘を全部0にすれば良いので簡単ですが、すでに運用段階に入ってる場合など、過去の指摘を全て直すのは現実的ではありません。

この場合は、masterの指摘数と比較して、今回の開発等で増えないことを指標とすると良いです。もちろん、たまたま修正が可能だったから減るって分には良いことなので褒める文化に。

Sonarはそれに適した機能があってTimeMachineで比較することが出来る。これを使うことで運用中のコードであっても、適用していくことが比較的簡単に出来ます。

f:id:pascal256:20140211132258j:plain

いずれにしても"指摘を増やさない"という運用が大事で、例外は原則認めてはいけない。そうしないとみんな守らなくなるからね。元のルールが厳しすぎるとかなら適度にカスタマイズすればいいし、うちもそうしてる。

あと、Issuee以外のDuplicationsとかComplexityは今はルールにしてない。この辺のルールを入れると縛りが強くなりすぎる気がしたので、あくまで開発者の参考レベル。

そして、怒る人重要。指摘を増やした状態で4や5にプロセスが行ってしまった場合は、きちんと怒る。必要に応じてマネージャとかもCCにして、全体周知して怒る。嫌われ役になっちゃいがちだけど、最初はみんな慣れてないから、ついやっちゃうし、新規メンバーもしてしまいがちなので、文化としてやっちゃダメなこと、とみんなが認識しきれるまでは、きちんと怒り役の人が居た方がうまく回るかな。

プラグインAPI

拡張性の高さもSonarの良いところです。単に対応している言語やテストツールを増やすだけではなく、PDF出力をはじめレポート類も充実しています。

Plugin Library - SonarQube - Codehaus

また、RESTベースのAPIで簡単に情報を取得したりも出来るので、独自のツールやExcelへの連携も簡単です。

たとえば、プロジェクト毎のIssuesとコードカバレッジの一覧は以下のURL。

http://localhost:9000/api/resources?metrics=coverage,violations,blocker_violations,critical_violations,major_violations,minor_violations,info_violations

f:id:pascal256:20140211132325j:plain

APIのドキュメントはこちら(Web Service API - SonarQube - Codehaus)を参考。

うちではこれを使って複数のブランチのタイムラインを1画面で見れるツールを作っています。コード品質が急激に悪くなったチームとかあれば、プロジェクト進捗にも影響するだろうから警戒する必要がありますし。

こういった拡張がさくっと書けるのは良いところです。

まとめ

色々書いてみましたが、この手のツールは単純に入れるだけじゃなくて、運用プロセスを作って文化まで昇格することが大事です。

とりあえず、勝手に導入して技術的な課題をクリアしたら現場メンバに周知。ある程度みんなが慣れたらマネージャとか偉い人系もレポートラインに加えて、進めるのが個人的には好きです。許可を取る前にやってしまえモデル。

導入も簡単だし、まずは入れてみて、自分たちの開発プロセスに合うかどうかを確認してみるのもいいと思います。

実際うちでは入れる前に比べて劇的にコード品質がマシになって、ヒューマンレビューではくだらないこと指摘せずに具体的なレビューに集中できるようになったし、効果があるケースも多いんじゃないかと。

それでは、Happy Hcking!

参考: