テストに役立つコードメトリクス トップ5

この記事はJim Holmesによるゲスト投稿です。

コードの状態を知ることは、テストの労力をより効果的に配分するのに役立つでしょう。静的解析メトリクスを利用すると、テスターは特に注意すべき領域に集中できます。

テスターの中には、コードメトリクスと聞くと尻込みしてしまう人もいるかもしれませんが、メトリクスの仕組みを理解することは、たとえばスレッド、同時アクセス、Web サービスのスケーラビリティ等の難しい問題を解決するコードの書き方を理解するのとは大きく異なります。技術的に高度なコードの書き方に関してそれほど深い知識がなくても、容易にソフトウェアメトリクスを利用できます。さらに、メトリクスは、優れたソフトウェアとはどのようなものかをテスターに教えるのに役立つ重要なツールです。

まず、この後で使う用語の意味を明確にしておきましょう。

ソフトウェア メトリクスは、ソフトウェア コードのさまざまな側面の計測値です。メトリクスは、コード全体にわたる高いレベルのものもあれば、クラス、メソッド、あるいはそれより低いレベルでコードの小さなブロックを対象とするものもあります。通常、メトリクスは静的解析または動的解析フェーズでツールによって収集されます。

動的解析はシステムの作動中に実施されます。静的解析はシステムを実際に実行することなく行われ、システムの動作ではなくコード自体の構造に着目します。なお、この記事では、静的解析時に収集されるメトリクスだけを扱います。

静的解析ツールは解析時にコードまたはシステムを検査し、特定の事項を計測します。さまざまなメトリクスに関して、計測値が一般的に許容される範囲内にあるかどうかを示す大まかなガイドラインが業界の過去の実績をもとに作成されています。最近の解析ツールであれば、メトリクスの計測機能と、メトリクスの標準的な許容値に関する参考情報を提供しているでしょう。

(残念ながら、メトリクスの「ベスト プラクティス」のようなものはありません。「ベスト プラクティス」など存在しないからです。メトリクスの結果は、組織全体のプラクティスや成熟度といったコンテキストの中で解釈される必要があります)

ソフトウェアの計測に利用できるメトリクスは多数あります。この記事では、私の経験から最も有用だと思うもの 5 つを取り上げます。5位から1位の順で発表していきましょう。

5) コードのコメント量

メトリクスの意味: コード内でのコメントの過剰な使用

コードのコメント量は、議論を呼びやすいトピックです。古い時代の開発プラクティスでは、膨大な量のコメントを書くことが推奨され、学界では、すべてのステートメントそれぞれにコメントを義務付けるプラクティスもあります。すべての、ステートメント、それぞれにです。

これが次のような書き方につながります。

int index = 0; //set index to 0

これでは、次のようにindexにセットする値を0から1へコードを変更したとき、コメントの修正が忘れられやすく、役に立たない情報によってコードが乱雑になるだけです。

int index = 1; //set index to 0

このようなコメントとコードの不一致は、バグ修正や機能拡張のために誰かがコードを読み返したときに大きな問題になります。コードが正しいのでしょうか?インデックスに値 1 をセットするのが本来の意図なのでしょうか?それともコメントが正しくて、インデックスに0をセットするべきなのでしょうか?

最近のプラクティスでは、コード自体の適切な名前付けを重視する方がよいとされています。コメントは、特に難しいロジックやドメイン固有のルールを記述するセクションの説明にだけ使用するべきです。誤解を招きやすい、重要な処理を行うブロックをメソッドとして抽出し、適切な名前を付けて意図を明確にします。短く簡潔で適切なコメントによって、「どのように」ではなく「なぜ」を説明します。

例(架空のサンプルであり、実際には動作しません):

public boolean IsShippingTypeValid(Product product, Order custOrder, IShippingLookup lookup){
    // 検索システムを呼び出し、配送状況を確認します。
    // 特定の宛先に対して重すぎる、または多すぎる場合は拒否します。
    // ルールの詳細については、IShippingLookupを参照してください。
    lookup.IsDestinationValidForProduct(custOrder.Destination, product);
}

メトリクスの使い方: メトリクスのレポートを見て、コメントが多いクラスやメソッドを探します。任意のエディターで該当クラスを開いて、コードが実際に行っていることとコメントの記述に不一致がないかを確認します。混乱や不一致があれば、どちらが正しいのかを判断できるかどうか、開発者に確認します。自動化されたテストがあれば、それを見て判断材料とします。該当機能をテストするテストシナリオ/探索チャーターを作成し、実行します。

4) コード行数

メトリクスの意味: 長すぎるクラス、モジュール、メソッド、ブロック

巨大なクラス、ブロック、またはメソッドは、行う処理や動作が多すぎるコードを示している場合があります。一般的に、長いセクションは分かりにくく、テストが難しく、保守が非常に大変です。

メトリクスの使い方: 長いクラスやメソッドを探します。ブロックは分かりにくくないでしょうか?データ接続を作成するいっぽうで、スレッドを作成したり、UI を更新するなど、異なる処理が混在していないでしょうか?コードから分離できるものがないかを確認し、開発者と協力して規模の大きなブロックのうちリスクが高い領域について議論します。やはり調査結果を基にテストシナリオを作成し、実行します。

3) 結合度

メトリクスの意味: 結合には2つの方向があります。着目しているコンポーネントをどれだけ多くのコンポーネントが使用しているか、そして着目しているコンポーネントがどれだけ多くのコンポーネントに依存しているかです。つまり、結合は内向的および外向的依存関係です。(内向的な結合を「求心性結合」と呼び、外向的な結合を「遠心性結合」と呼びます)。

多くの結合を持つコンポーネントには、2 つの点でリスクがあります。検査対象のコンポーネントに 多数の他のコンポーネントが依存している場合、対象コンポーネントを変更すると、他のコンポーネントが動作しなくなるリスクがあります。

反対に、対象コンポーネントが多数の外部コンポーネントに依存している場合、多数のコンポーネントの影響を受ける可能性があるため、対象コンポーネントが動作しなくなるリスクが高まります。

メトリクスの使い方: それぞれの方向で結合度が高いコンポーネントを探します。外部コンポーネントに動作を破壊するような変更を加え、検査対象コンポーネントがどのように反応するかを確認します。上記の反対を行って外部コンポーネントをテストします。自動化された単体テストおよび統合テストを実行し、対象コンポーネントが十分に保護されているかを検査します。必要に応じてテストを強化します。さまざまなコンポーネントの API テストを調べて品質の問題への理解を深めます。

2) チャーン

メトリクスの意味: チャーンはソースコードファイルに加えられた変更の量です。通常は、ソース管理システムに特定のファイルがコミットされた回数で測られます。

チャーンの値が高いファイルは、多数の変更が加えられているシステム領域を表します。例外はありますが、ファイルが頻繁に変更されていることは、そのファイルに品質の問題があることを表しているのが普通です。そのような品質の問題には、分かりやすいものもあります。たとえば、理解が難しい、脆弱な処理が含まれる、多数のバグフィックスが必要である場合などです。しかし、品質の問題はもっと分かりにくい場合があります。クラスやコンポーネントの設計が悪いため、拡張したりシステムの他の領域を変更しようとしたとき、修正が難しいケースなどです。

メトリクスの使い方: チャーン値の高い領域を探します。そのようなクラス、モジュール、パッケージ等を探索します。結合度の場合と同様に、自動化された回帰テストがしっかりなされていることを確認します。必要に応じて、リスク/バリューアプローチに基づいてテストを拡張します。ファズテストやその他の高影響度アプローチによってチャーン値の高い領域を重点的に検証します。

1) 複雑度

メトリクスの意味: サイクロマティック複雑度は、コードブロックを通る独立したパスの数です。パスが多いほど、コードのテストと保守は難しくなります。ネストされたIF/ELSE文、複数のSWITCH/CASEブロックやこれらに似た構文があると、サイクロマティック複雑度はすぐに危険な領域にまで跳ね上がります。

サイクロマティック複雑度は、コードの品質や状態をすばやく知りたいと思うとき、私がよく使用する一番のメトリクスです。複雑度の数値が高い、あるいは飛びぬけて高いことは、チームの成熟度、デザイン思考、掛け値のないソフトウェアエンジニアリングスキルなどについて多くを示唆します。そして示唆されるのはとてもよくない事態です。

複雑度が高いと、ブロックの意図された動作を明確に表現できなくなり、ブロックを読み直す作業が間違いを起こしやすい苦行になります。そのうえ、研究によれば、複雑度の高さと欠陥率の高さには正の相関があることが分かっています。

メトリクスの使い方: 複雑度メトリクスが正常値を超えているブロックを高い方から順に確認します。最も複雑度が高いセクションにチャーンメトリクスを重ね合わせます。該当ブロックのバグ履歴(オープン中のバグおよびクローズされたバグ)を特定できるか確認します。これらのデータを基にした仮想的なベン図のうち、最もリスクの高い領域からテストを開始します。

静的解析メトリクス: 学ぼう。使おう!

静的コード解析メトリクスは、コードの全体的な状態について豊富な情報を提供してくれます。メトリクスを利用すると、それほど注意を必要としない堅固な領域が分かり、テスターが貴重な時間をどこに割くべきかを判断するのに役立ちます。

あなたはテストの情報源として静的コード解析を利用していますか?どんな点がより高い価値を届けるのに役立っているか、コメント欄で教えてください。

JimはPillar Technologyのエグゼクティブコンサルタントとして、さまざまな組織のソフトウェアデリバリープロセスの改善を支援しています。Guidepost Systems のオーナー/運営者でもあり、課題に取り組んでいる組織と直接的に関わっています。1982年にアメリカ空軍に入職して以来、IT業界のさまざまな領域での経験があります。長年にわたってチームや顧客がすばらしいシステムをリリースできるよう支援してきたほか、LAN/WANおよびサーバー管理業務にも携わりました。新興企業からFortune 10企業まで、幅広い組織に協力し、デリバリープロセスを改善して顧客によりよい価値を届けられるようサポートしてきました。プライベートでは、キッチンでワイングラスを手にしていたり、Xboxをプレイしたり、家族とハイキングを楽しんだり、ギターを練習しようとしてガレージに追いやられたりしています。

(この記事は、開発元Gurock社の Blog 「Top Five Code Metrics to Help You Test Better」2019年1月22日の翻訳記事です。)

関連する製品

テスト管理ツール TestRail

脱Excel!テスト管理をシンプルにするWebベーステスト管理ツールのトップブランド

Webベースのテスト管理ツールのトップブランドであるTestRail。テストケースの管理やテスト結果の記録、チームでの情報共有など、Excelを使ったテスト業務に限界を感じていませんか?TestRailはシンプルで使いやすいUIを提供し、テストにかかるさまざまな管理コストの削減に貢献します。

TestRailの詳細はこちら>>>

ソースコード解析ツール Understand

ソースコード解析ツール

大規模なプログラムや複雑なプログラムをすばやく理解するためのさまざまな機能を搭載しています。アーキテクチャから個々の機能まで、あらゆるレベルでソースコードを分析し、プログラムの制御フローや構造、クラス継承、関数や変数の関係など、多彩な角度からソースコードをビジュアル化します。 

Understandの詳細はこちら>>>

eBook 公開中

Paul Gerrard著 効果的なテスト管理12の秘密 (日本語)

テスト計画やテスト管理に役立つ12のトピックを解説します。

詳細はこちら