Tutorials

チームを強化するコード品質メトリクス 6 選

Read this post in other languages:

ほとんどのソフトウェア開発者がコード品質を完璧にすることを共通の目標としています。この目的は分かりやすくはありますが、その達成方法は複雑な場合があります。 レビュープロセスの結果を改善するには、何をどのように測定するかが重要になります。

これは、継続的な改善、技術的優位性への不断の注意、および定期的な反省を基本理念としているチームに特に当てはまります。 ソフトウェア開発分野で 20 年以上の経験を持つ JetBrains がチームに最も効果的だと思われるメトリクスに関する情報を提供するためのインサイトを収集しました。

実用的なコード品質メトリクスと測定方法

1. サイクロマティック複雑度(CYC)

CYC はソースコード内の独立パスの数に基づいたプログラムのコードフローの複雑度を測定した値です。 複雑度が増すにつれてコードの理解、テスト、および保守も困難になるため、これは重要なメトリクスです。  アジャイル手法を採用しているのなら、持続可能性と保守可能性が重要となります。 このような場合、CYC によって単純化が必要と思われる箇所のインサイトを得ることができます。

このメトリクスの仕組みを簡単な例を使って説明しましょう。 条件や分岐を使わず、ステートメントを順次実行するだけのコードスニペットについて考察します。

public int sum(int a, int b) {
   System.out.println("Adding two numbers: " + a + " + " + b);
   return a + b;
}

このコードには分岐がないため、どんなパラメーター値の組み合わせでも関数内のすべてのステートメントが実行されます。 したがって、このコードの CYC の結果は 1 となります。

入力をチェックする条件ステートメントを導入すると、コードには 1 つの分岐でなく実行されうるパスが 2 つ含まれることになるため、CYC は 2 倍になります。

public int sum(int a, int b) {
   if(a < 0) throw new IllegalArgumentException("Parameter a should be positive");
   System.out.println("Adding two numbers: " + a + " + " + b);
   return a + b;
}

第 2 パラメーターをテストする別の条件を追加すると、CYC の結果は 3 に増加します。

public int sum(int a, int b) {
   if (a < 0) throw new IllegalArgumentException("Parameter a should be positive");
   if (b < 0) throw new IllegalArgumentException("Parameter b should be positive");
   System.out.println("Adding two numbers: " + a + " + " + b);
   return a + b;
}

すべての条件ステートメントまたはループブロックはメソッドの CYC メトリックに加算されるため、すべてのコード分岐を通して実行するのに必要なテストの数が増えることなります。

CYC 値が高くても、それが直接的にコードにバグや破綻が生じていることを示唆しているわけではありません。しかし、コードの保守が困難で、新しい変更を加えると容易に破綻する可能性があるということを示唆しているのは間違いありません。 IntelliJ IDEA には過剰に複雑なメソッドについてエディター内で直接通知する機能があります。 Overly complex method(過剰に複雑なメソッド)インスペクションのしきい値は、Settings(設定)| Editor(エディター)| Inspections(インスペクション)で構成できます。

JetBrains Qodana による重複解析。重複コードを検出します。

このしきい値はデフォルトで 10 に設定されています。 しかし、このメトリクスを 2 に変更した場合、以下のコードの例はエディターによってハイライトされます。

静的コード解析の例。

このインスペクションをプロジェクト全体に対して有効化する方法

Qodana をサーバーサイドコード解析(ローカルだけでなくチーム全体のコード品質を追跡)に使用している場合は CYC を自動的にチェックできます。 Recommended(推奨)プロファイルを選択し、コーディングしている言語に対してこのインスペクションが有効化されていることを確認してください。

JetBrains Qodana でコードの複雑度チェックを有効化する。

結果の解釈

(米国)Tom McCabe Jr. 氏による国土安全保障省向けの「Software Quality Metrics to Identify Risk」プレゼンテーション(ダウンロード)では、メソッドの CYC メトリクス値が 10 未満ならばコードを十分に単純だと見なせると述べられています。

メトリクスが 50 を超えた場合、コードは過剰に複雑であり、テスト不可能と見なされます。 ただし、実務上は 6 未満の値を目標とし、結果が 10 を超える場合には警告を出すように設定することをお勧めします。 この警告により、関数を単純化して複雑度の増加を防ぐ時期が来たことを知ることができます。

以下は弊社が提案する CYC スコアの範囲です。

  • 1~5 – 単純なコード。テストとデバッグを簡単に実行が可能
  • 6~10 – やや複雑。中程度のリスク
  • 10~20 – 高いリスク。要注意
  • 20 以上 – 非常に複雑なコード。理解も保守も困難

2. コード重複率

コード重複率は、コードベースの複数箇所に同一または類似したコードがどれくらい出現しているかを明確にするのに役立ちます。 コード重複率が高いと保守作業の増加、バグの混入確率の増加、およびコード可読性の減少を招く可能性があるため、これは重要なメトリクスです。

Qodana ではデフォルトで重複チェックが有効化されていますが、WebStorm や Rider などの IDE や IntelliJ IDEA でも重複検出を構成できます。

Qodana のコード重複率チェック。
Qodana による重複のチェック。

結果の解釈

コードの重複率は 5% 未満に抑えるのが理想です。 そうすることで不要なリファクタリングを回避できます。つまり、1 つの改善や課題に対してコードの多くの部分を変更する必要がなくなります。 Qodana などのツールを使って、ローカルまたはサーバーサイドで継続的にコードの重複を監視するようにしましょう。

3. コード(テスト)カバレッジ

カバレッジを最大化したテストケースを作成すると、手動テストの前にソフトウェアが期待どおりに動作することを検証できます。 より効果的なテストを行えば、高品質な製品をより素早く市場に出せる可能性も高まります。

また、テストカバレッジが高いと保守性が向上し、冗長なコードに注意を向けられるようになります。なぜなら、測定はカバレッジが高いほどコードの欠陥が少なくなるという仮定に基づいて行われるためです。

コードテストカバレッジを判断する最も一般的な方法として、コードの行数による測定があります。

コードカバレッジ率 = (アルゴリズムがテストするコードの行数 ÷ システムコンポーネントの全コード行数)× 100

ただし、他にも以下の 2 つの手法があります。
1)ステートメントによる測定
2)分岐による測定。複雑度はコードをカバーするために実装する必要のあるテスト数を示すため、こちらのほうがサイクロマティック複雑度メトリクスに関連性が強いです。

コードカバレッジの評価

Qodana Ultimate または Ultimate Plus ライセンスをお持ちの場合は JVM、JS、または PHP 用の Qodana を使用することで、qodana.recommended または qodana.starter プロファイルでコードカバレッジテストを実行できます。 こちらでコードカバレッジ測定のセットアップ方法をご覧ください。

JetBrains Qodana によるコードカバレッジテスト。

4. 発生しうるバグの数

コード内のバグの数をできる限りゼロに維持したいと考えるのは当然のことですが、コード解析をすればあらゆる種類のバグを特定できます。 一例としては、オブジェクトが必要な場合に演算を実行しようとしているときに発生する NullPointerExceptions が挙げられます。 これは実行時に null であるオブジェクトインスタンスに対してメソッドを使用しているか、そのインスタンスの変数にアクセスしようとした場合によく発生します。

このような問題は早期に発見し、バグを含むバージョンの製品をリリースしないようにすべきです。コード内だけでなく、ピアレビュー作業中でもすぐに気付かない可能性があればなおさら重要です。 Qodana はデータベース接続が使用後に安全に閉じられていないなど、不適切なリソース処理に関連する問題を簡単に阻止できます。

5. コードの臭い

ソフトウェアコードベースの健全性を維持するには、廃止された API の使用などのコードの臭いを測定することが重要です。 廃止された API の使用箇所はレビュー担当者に特定させ、廃止された API の代替実装を提案させることで手動で使用箇所を判断できますが、Qodana などの静的コード解析ツールを使用するのが最も一般的な手法です。

6. 脆弱性の数

コードの脆弱性とは、セキュリティ侵害、データ漏えい、またはその他のセキュリティ関連の問題を引き起こす可能性のあるセキュリティ上の弱点または課題を指します。

脆弱性が 1 つあるだけで、大きなセキュリティ侵害に発展する可能性があります。 それは Log4J の脆弱性による影響を大きく受けた X(旧 Twitter)、CloudFlare、および AWS の例を見るだけで分かるでしょう。 このような脆弱性は、セキュリティ脆弱性、構成の誤り、アクセス制御の問題、依存関係の脆弱性など、さまざまな形で表面化します。

JetBrains Qodana Cloud ダッシュボードのセキュリティ脆弱性。

上記は、Checkmarx の機能を借りて脆弱性のある依存関係を示す Qodana Cloud のチェックです。 Qodana のデータを使って依存関係のライセンスをチェックすることも可能です。

コード内の脆弱性の数を確定したら、どれが重大であり、最も大きなリスクを示しているかを判断できます。 そのまま最も優先度の高い課題に着手し、それほど重大でない課題はベースラインに保存して後で解決することができます。

静的コード解析によるコード品質測定の単純化

コード品質メトリクスを使うことで、より効率性と保守性の高いさらにクリーンなコードに近づけることができます。 これらのメトリクスによってプロジェクトの健全性を長期にわたって俯瞰できるため、製品の改善とチームコラボレーションの面で先着的に優位に立つことができます。

デリバリープロセスにこれらのメトリクスの導入をお考えなら、Qodana にお任せください。 CI/CD ワークフローにぴったり適合するため、チーム全体でコード品質に関して信頼できる唯一の情報源を得られます。 さらに、そのスキャン結果はすぐに JetBrains IDE で利用できるため、課題を迅速に解決できるようになります。

今すぐお試しになり、最も頻繁に使用しているメトリクスについてぜひシェアしてください。 まずは以下のボタンをクリックして開始しましょう。 コード品質の測定方法をより詳しくお知りになりたい場合は、弊社までお問い合わせください。

Qodana を無料で試す!

オリジナル(英語)ブログ投稿記事の作者:

このエントリーをはてなブックマークに追加

image description