そこに仁義はあるのか(仮)

略してそこ仁!

SonarQubeで始めるコード品質チェック

「テストも通ってるし、レビューも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画面から以下のように進めます:

  1. SonarQubeにログイン後、「Create new project」をクリック
  2. 「Manually」を選択
  3. プロジェクトキーとプロジェクト名を入力(例:sample-project
  4. 「Set Up」をクリック
  5. 「Locally」を選択
  6. トークンを生成し、安全な場所に保存します

プロジェクトの設定ファイル

プロジェクトのルートディレクトリに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を使用することで、コードの品質を継続的に監視し、問題を早期に発見できます。特にチーム開発では、共通の品質基準を設けることで、ある程度のコードの一貫性と保守性を高めることができます。

とくにチーム開発では以下のようなメリットがあり、レビューの負担軽減や品質の底上げにもつながります。

  • 品質ゲートで「最低限守りたいライン」を共有できる
  • バグやコードスメルを自動で検出してくれる
  • 読みにくいコードを早期にリファクタリングできる