「テストも通ってるし、レビューもOK。でもなんだかバグが出やすい…」「関数が長くなって、後から読むとわかりづらい…」 など、コードを書く上で可読性を含んだ「品質」はとても大切な要素です。
今回は、そんな“コードの内側の問題”を見える化してくれるツール、SonarQubeを紹介します。
最初の会社にいたときは使ってたツールではあったのですが、ここしばらく会わず、最近再開したので導入手順などをまとめておきます。
🛠 SonarQubeってどんなツール?
SonarQubeは、コードの品質や保守性、セキュリティの問題を自動で検出してくれるオープンソースのツールです。
以下のような観点で、コードを分析してくれます。導入してCI/CDのプロセスに組み込むことで、常にコードの品質を確認できます。
- バグやコーディング規約違反の検出
- コードの重複や複雑さの分析
- テストカバレッジの可視化
- セキュリティの脆弱性チェック(例:SQLインジェクションの可能性など)
最近はAIでのコード品質測定なども話題になりますが、都度ではなく継続して数値として評価してくれるというニーズは今でも十二分にあると思います。
🚀 SonarQubeを導入する
1:SonarQubeをインストールする
Dockerを使ったインストール
docker run -d --name sonarqube -p 9000:9000 sonarqube:lts
macOSでのインストール(Homebrewを使用)
brew install openjdk@17 brew install sonarqube brew services start sonarqube
いずれかの方法でSonarQubeのインストールと起動が完了したら、http://localhost:9000 にアクセスし、初期ユーザー名/パスワード(admin/admin)でログインします。初回ログイン時にパスワードの変更が求められます。
2:JavaプロジェクトをSonarQubeに登録する
SonarQubeが起動したら、次はプロジェクトを登録して分析の準備をします。
プロジェクト作成
SonarQubeのWeb画面から以下のように進めます:
- SonarQubeにログイン後、「Create new project」をクリック
- 「Manually」を選択
- プロジェクトキーとプロジェクト名を入力(例:
sample-project
) - 「Set Up」をクリック
- 「Locally」を選択
- トークンを生成し、安全な場所に保存します
プロジェクトの設定ファイル
プロジェクトのルートディレクトリにsonar-project.properties
ファイルを作成します。
sonar.projectKey=sample-project sonar.projectName=Sample Project sonar.projectVersion=1.0 # ソースコードのパス sonar.sources=src/main/java sonar.java.source=17 # コンパイル済みクラスのパス sonar.java.binaries=build/classes/java/main # テストコードのパス sonar.tests=src/test/java sonar.java.test.binaries=build/classes/java/test # JaCoCo レポートのパス(カバレッジ情報) sonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml # エンコーディング sonar.sourceEncoding=UTF-8 # 除外パターン(自動生成コードなど) sonar.exclusions=src/gen/**/*
Gradleプロジェクトの設定
JaCoCoの設定もしているのですが、これはSonarQubeにテストカバレッジをレポートするために必要です。SonarQubeは自前でテストを実行しないため、JaCoCoなどのツールでXML形式のカバレッジレポートを生成し、その結果を取り込む必要があります。
build.gradle
ファイルにSonarQubeとJaCoCoのプラグインを追加します。
plugins { id 'org.sonarqube' version '4.4.1.3373' id 'jacoco' } jacoco { toolVersion = "0.8.10" } jacocoTestReport { reports { xml.required = true } } test { finalizedBy jacocoTestReport }
3. コード分析の実行
Gradleを使った分析
事前にテストとカバレッジレポートを生成した上で以下を実行します:
./gradlew clean test jacocoTestReport sonarqube \ -Dsonar.host.url=http://localhost:9000 \ -Dsonar.login=YOUR_SONAR_TOKEN
SonarScannerを使った分析
SonarScannerを使う場合は、事前にビルドとテストを済ませておきます。
brew install sonar-scanner
sonar-scanner \ -Dsonar.host.url=http://localhost:9000 \ -Dsonar.login=YOUR_SONAR_TOKEN
4. 品質ゲートの設定
品質ゲートは、コードの品質を一定の基準でチェックするためのルールセットのようなものです。例えば「テストカバレッジ80%以上」とか「新しく追加されたコードにバグがないこと」など、チームとして守りたいラインを明確にできます。
SonarQubeでは、デフォルトで「Sonar way」というルールが用意されています。
5. 関数の複雑度について
「この関数ちょっと長すぎるかも…」「条件分岐が入り組んでて読みにくいな…」と思ったことはありませんか?そんなときに便利なのが、関数の「複雑度」を数値で見える化してくれるSonarQubeの機能です。
SonarQubeでは、主に以下の2つの指標を使ってコードの複雑さを評価します:
- 循環的複雑度(Cyclomatic Complexity):分岐の数に基づいた複雑度を表す指標
- コグニティブ複雑度(Cognitive Complexity):コードの読みやすさや理解のしやすさを考慮した指標
デフォルトではコグニティブ複雑度にルールが有効になっていて、例えば15を超えると複雑すぎるとSonarQubeが教えてくれます。 もし循環的複雑度を使いたい場合は、SonarQubeの品質プロファイルで対応するルールを有効にする必要があります。
循環的複雑度に対してもルールを有効にすれば同様に閾値ベースで検出できます。必要に応じて品質プロファイルから有効化・閾値変更を行います。
📝 まとめ
SonarQubeを使用することで、コードの品質を継続的に監視し、問題を早期に発見できます。特にチーム開発では、共通の品質基準を設けることで、ある程度のコードの一貫性と保守性を高めることができます。
とくにチーム開発では以下のようなメリットがあり、レビューの負担軽減や品質の底上げにもつながります。
- 品質ゲートで「最低限守りたいライン」を共有できる
- バグやコードスメルを自動で検出してくれる
- 読みにくいコードを早期にリファクタリングできる