ホーム/ドキュメント/技術的負債/CppDepend 技術的負債の見積もりと管理

CppDepend 技術的負債の見積もりと管理

はじめに

今日、技術的負債の比喩はソフトウェア業界で広く採用されています。造語者は Ward Cunningham 1992年に。

これ 参考記事 Martin Fowler によるこの本は、技術的負債の比喩を詳細に説明しています。M. Fowler の言葉を引用します:

このメタファーでは、迅速でずさんな方法で物事を行うと、金銭的負債に似た技術的負債を抱えることになります。金銭的負債と同様に、技術的負債には… 利子 支払いは、迅速でずさんな設計の選択のために、将来の開発で行わなければならない余分な労力という形で発生します。利息を払い続けることを選択することも、迅速でずさんな設計をより良い設計にリファクタリングすることで元本を返済することもできます。元本の返済にはコストがかかりますが、将来の利息支払いが減ることで利益を得られます。

CppDependを使用して、 コード ルールは C# LINQ クエリで記述できます。 コードベースに適用されると、ルールは問題を生成します。C# で記述された数式を通じて、問題の技術的負債と年間利息の両方を推定する専用の負債 API が提供されています。問題の技術的負債と年間利息はどちらも人時で測定されます。

  • この 技術的負債 は問題の修正にかかる推定工数です。
  • この 年利 は、問題が未修正のままの場合に年間消費される推定工数です。これは次の推定値を提供します ビジネスへの影響 問題の。

例:

warnif count > 0
from m in Methods
where m.CyclomaticComplexity > 10
select new {
   m,
   m.CyclomaticComplexity,
   Debt = (3*(m.CyclomaticComplexity-10)).ToMinutes().ToDebt(),
   AnnualInterest = (m.PercentageCoverage == 100 ? 10 : 120).ToMinutes().ToAnnualInterest()
}

この例では、ルールは複雑すぎるメソッドに一致します。複雑さは次で測定されます 循環的複雑度 コードメトリクス。確認できること:

  • この 技術的負債 特定のしきい値を超える複雑さに比例します。
  • この 年利 メソッドがテストで 100% カバーされている場合は年間 10 分、それ以外は年間 2 時間です。

複雑なメソッドをリファクタリングもテストカバレッジもないまま放置することは、エラーが発生しやすい状況です。最良の場合でもそのような状況はコードの保守性を損ない、最悪の場合は本番環境でのバグにつながります。年間利息は次を推定します 平均 複雑なメソッドがリファクタリングされない場合の年間コスト。メソッドがテストでカバーされていない場合はさらに悪化します。次の語 平均 ここで強調されているのは、たとえば 8 つの複雑でテストされていないメソッドのうち、発見、調査、修正、提供に 2 人日(2×8 時間)かかるバグを持つのは 1 つだけかもしれないという事実によるものです。

既定ルールセットの各ルールには、各問題の技術的負債と年間利息を計算する数式が含まれています。ルールと数式は、Visual Studio で編集可能な生の C# であるため、チームのニーズや習慣に合わせて作成およびカスタマイズできます。主な利点は、 技術的負債の見積もりは完全に透過的で、CppDepend で簡単にカスタマイズできます。

年利と重要度

年利はの指標 問題の重要度. 重要度と年間利息は同じ概念を表します 年間利息は連続的な尺度であり、重要度は離散的な尺度です。

CppDepend は 5 つの重要度レベルを定義し、問題の重要度は年間利息に基づくしきい値によって推定されます。

  • : 重大度レベルが Low の問題は、小さな改善、つまりコードをよりエレガントに見せる方法を表します。既定の Annual Interest しきい値:ゼロまたは年間 2 人分未満。
  • : 重大度レベルが Medium の問題は、修正されなくても開発に重大な影響を与えない問題に対する警告を表します。既定の Annual Interest しきい値:年間 20 人分未満。
  • : 重大度レベルが High の問題は迅速に修正すべきですが、次のスケジュールされた間隔まで待つことができます。既定の Annual Interest しきい値:年間 2 人時未満。
  • 重大: 重大度レベルが Critical の問題は本番環境に移すべきではありません。業務上の差し迫った必要性のために移行することは可能ですが、遅くとも次のイテレーションで修正する必要があります。既定の Annual Interest しきい値:年間 10 人時未満。
  • ブロッカー:Blocker 重要度レベルの問題は本番環境に移行できません。 必要 修正されます。Annual Interest のデフォルトしきい値:年間 10 人時以上。

の概念に注意 重大な問題 の概念とは異なります 重大ルール。問題の重大度は、そのルールがクリティカルかどうかとは関係ありません。ルールに何らかの制約を適用するためにクリティカルとしてタグ付けすることができ、たとえばクリティカルルール違反時に失敗する Quality Gate を記述できます。

重大ルール

負債設定

技術的負債の計算と結果は、パネルの設定で微調整できます CppDepend > プロジェクト プロパティ > Issues and Debt.

CppDepend技術的負債設定

確認できます:

  • 前のセクションで説明した、問題の重要度と年間利息に関するしきい値
  • SQALE 負債評価に関するしきい値は次のセクションで説明します
  • すべての技術的負債および年間利息の推定値に適用できる 2 つの乗算係数。既定では、これらの係数は 1 に設定されています。
  • 負債の見積もりが意味のある工数の尺度で表示されるようにするには、次に関する設定 1日の勤務時間数 または 年間勤務日数 調整できます。
  • 負債値の書式設定方法を選択したり、変換したりする設定もあります 人時の負債値金銭コストの負債値.
人時の負債値

SQALE負債比率と負債評価

この SQALEメソッド (一般に「scale」と発音)は、技術的負債を評価する標準化された方法です。CppDepend は次を実装しています 負債比率負債評価 SQALEメソッドの一部。

この 負債比率 コードベースまたはコード要素について、コード要素をゼロから書き直すのにかかる推定労力と比較した、推定技術的負債の割合(パーセント)で表されます。コード要素をゼロから書き直すのにかかる推定労力は、コード要素のコード行数と次から推測されます 負債設定 名前付き 1,000 の論理コード行を開発するための推定人日数 (前のセクションの負債設定に関するスクリーンショットを参照)。

1,000 の論理コード行を開発するための推定人日数 設定は単なる推定であるため、短期的には意味がありません。数人月または数年の開発の後、この値は通常、推定目的で信頼できるほど十分に安定します。この推定設定は、単体テストの作成コストも考慮に入れる必要があります。既定値は 18 人日で、平均 55 の新しい論理コード行に相当します。 単体テストで100%カバー、1日1開発者あたり。

この 負債評価 コードベースまたはコード要素のものは、Debt Ratio に適用されるしきい値から推測されます。Debt Rating は A、B、C、D、E の範囲です。4 つのしきい値は、負債設定パネルでカスタマイズできます(負債設定に関する前のセクションのスクリーンショットを参照)。既定のしきい値は次のとおりです。

  • Debt Ratio が [0, 5%[ の場合、負債評価は A になります。
  • Debt Ratio が [5%, 10%[ の場合、負債評価は B になります。
  • Debt Ratio が [10%, 20%[ の場合、負債評価は C になります。
  • Debt Ratio が [20%, 50%[ の場合、負債評価は D になります。
  • Debt Ratio が 50% 以上の場合、負債評価は E になります。

コード ベースの Debt Rating と Debt Ratio の値はダッシュボードに表示されます。セクション 技術的負債の参照 単純な C# コード クエリで、任意のコード要素の Debt Ratio と Rating の値を表示できることを示します。

CppDependダッシュボードと負債評価

問題修正の優先順位付けと Breaking-Point メトリック

この ブレイキングポイント 問題または問題セットについて、問題の修正にかかる推定コストが、問題を修正しないままにしておく推定コストに達するまでの、現在からの時点です。

ブレイキングポイントは 負債を年利で割った値。たとえば、負債の修正にかかる推定コストが 10 人日で、推定年間利息が年間 2 人日の場合、損益分岐点は現在から 5 年後となります。

ブレイキングポイントに注意 より低い 年という単位は、今後 12 か月間、負債を修正する方が修正しないよりも安価になると推定されることを意味します。

損益分岐点は、負債や年間利息(人月または人年)のような人時ではなく、通常の期間(月または年)で測定されることにも注意してください。損益分岐点の値は TimeSpan 型です。

に関しては 最初に修正すべき問題の優先順位付け、問題の重大度は重要なパラメーターです。補足すると、重大度は年間利息の離散的な尺度です。したがって、年間利息が高いほど、修正が重要になります。

ただし、特定の重大度レベルが与えられても、すべての問題が同等というわけではありません。修正により多くの労力を要するものもあります。これは技術的負債の指標で推定されます。したがって、次を推定するには 投資収益率 (ROI) 問題の修正については、負債を年間利息で割って推定することに意味があります。この推定は損益分岐点であり、値が低いほど ROI が高くなります。

デフォルト ルールのセットでは、ベースライン以降の新しい問題に関連する問題(次のようなもの)は、 API破壊的変更, さらに悪化するコード要素の品質, テストされていない新しいコード要素... は、他の問題よりも高い年間利息、ひいては高い重要度を生じさせる問題です。これは次に準拠しています 最近導入された問題を最初に修正するベスト プラクティス.

問題修正の優先度

技術的負債の参照

はじめに見たように コード ルールは C# LINQ クエリを通じて実装されます また、負債と年間利息の見積もりは、これらの LINQ クエリに埋め込まれた式から推論されることも確認しました。

これ C# LINQクエリスキーム さらに進んで、技術的負債を参照・探索するために使用できます。ドメイン 問題 は、コードベースで見つかったすべての問題の列挙です。当然ながら、このドメインに依存するクエリは、すべてのルールが実行された後に実行されます。

たとえば、ダッシュボードで次のような問題数をクリックすると ベースライン以降の新たな重大問題 以下の例では、関連する問題を一覧表示するコードクエリが生成されます。問題はルールごとまたはコード要素ごとにグループ化できることに注意してください。下のスクリーンショットでは、問題はルールごとにグループ化されています。

ベースライン以降の重大な問題

ダッシュボードの Explore Debt メニューに注目してください。これは、ルール、問題、コード要素に関するクエリを生成し、技術的負債を深く調査します。

ダッシュボード負債探索メニュー

右クリック ルールカテゴリ、のように コードカバレッジ ここのカテゴリには、このカテゴリの問題をクエリするメニューが表示されます:

カテゴリごとに問題を選択

デフォルトの負債と問題のクエリは次の場所にあります ホットスポット グループ。例えばクエリ 型ホットスポット 負債の多い型を先にリストします。

型ホットスポット

この ルール ドメインは、すべてのアクティブなルールの列挙です。違反されたルールと違反されていないルールの両方を一覧表示します。負債と問題の数ごとにルールを一覧表示するクエリを記述できます。一致したルールはカテゴリでグループ化できます。

当然のことながら、カバレッジ、コード品質、アーキテクチャは、最も多くの負債と問題を生じさせることが多いカテゴリです。

ルールごとの負債と問題

ベースライン以降の新規または修正された問題は最近の作業の品質を評価するため、問題セットを調査する際にベースラインは重要な役割を果たします。

既定では、ベースラインは 30 日前に最も近い履歴分析結果であり、既定では履歴分析結果は最大で 1 日 1 回保存されます。

最近の作業品質を評価する際には、昨日、先週、先月のベースラインを使い分けたいことでしょう。CppDepend ダッシュボードでは、 一時 ワンクリックでベースライン。負債と問題のセットは、数秒以内にそれに応じて再計算されます。

一時ベースラインを選択

ベースライン以降の問題と負債の評価が重要であるため(先ほど説明したとおり)、すべて ホットスポット デフォルトクエリにはが付属 ベースライン以降 バージョン。たとえば、評価するためのクエリは次のとおりです ルールごとの新規負債と問題 ベースライン以降。

ルールごとの新規負債と問題

負債と問題のクエリに関する微妙な点に触れておきましょう。型はメソッドとフィールドを含み、名前空間は型を含み、アセンブリは名前空間を含みます。したがって、型、名前空間、アセンブリはコード要素の親です。

問題関連のすべて ICodeElement 拡張メソッド elem.Debt(), elem.AnnualInterest(), elem.Issues()、バージョンの先頭は すべて 親コード要素とそのすべての子要素の負債と問題を返します。したがって:

  • elem.AllIssues() 親コード要素の問題とその子コード要素の問題の列挙を返します。製品内では、用語として次の表現を使用することがあります 累積問題 アセンブリ、名前空間、型などの親コード要素のもの。
  • elem.AllDebt() 親コード要素とその子コード要素の推定合計負債を返します。
  • elem.AllAnnualInterest() 親コード要素とその子コード要素の推定合計年間利息を返します。
  • elem.AllBreakingPoint() 親コード要素とその子コード要素の推定ブレイキング ポイントを返します。

技術的負債とクオリティゲート

技術的負債と問題に関するデフォルトの Quality Gates があります。次を含みます 負債の割合, ベースライン以降の新規負債 または 新規ブロッカー/重大/主要な問題。絶対的な技術的負債値に関連する Quality Gate は既定で無効になっています。適切なしきい値は、特定のプロジェクトのコンテキストでのみ定義できるためです。

クオリティゲート編集

同じように 問題ルール は、問題やルールの列挙を提供するクエリ可能なドメインとして事前定義されています。ドメイン QualityGates は Quality Gate の列挙です。以下の既定のクエリは、ベースライン以降の Quality Gate の傾向を推定します。ベースラインに依存する Quality Gate(例: ベースライン以降の新規負債) はベースラインに値もステータスも定義されていません。

クオリティゲートの推移

技術的負債がゼロまたは不完全になる理由

  • 技術的負債の見積もりがゼロまたは?を示す
    技術的負債がゼロまたは ? の場合、古いバージョンの CppDepend(v6 以下)で作成されたプロジェクトを分析している可能性があります。以前の CppDepend バージョンのルールセットには負債の数式がなかったため、既定では負債の数式のない問題の負債はゼロになります。
    内で ダッシュボード > 負債パネル という名前のリンクが表示されます デフォルトルールでルールファイルを作成.
    デフォルトルールでルールファイルを作成
    このリンクをクリックすると、負債推定数式を持つすべての新しい既定ルールを含むルールファイルが自動的に作成されます。完了したら、実際のプロジェクトルールを技術的負債を推定するルールに置き換えることをお勧めします。そのためには、次からドラッグ&ドロップを使用できます クエリとルールエクスプローラー パネル(ルールとルールグループの両方)。負債の数式は、CppDepend の下位バージョン(v6 以下)で読み取るとルールのコンパイルエラーを引き起こすことに注意してください。このプロジェクトを CppDepend v6 以下で使用する予定がある場合は、まずクローンしてください。
    カスタマイズされたルールについては、ソース コードを変更してカスタムの負債見積もり式を記述することをお勧めします。
    最後に、既定のルールファイルはプロジェクトファイルと同じディレクトリに作成され、相対ファイルパスでプロジェクトに添付されることに注意してください。このパスは、次から編集できます CppDepend プロジェクト プロパティ > Paths Referenced.
  • コード カバレッジ データが提供されていないため、技術的負債の見積もりが不完全です
    単体テストでテストされていない、または部分的にしかテストされていないコードは、技術的負債の大きな原因となります。実際、テストでカバーされていないコード行はすべて技術的負債に寄与します。そのため、ダッシュボードの Debt セクションは、次の場合に警告メッセージを表示します コードカバレッジファイルのインポート CppDependプロジェクトで設定されていません。
    カバレッジ データが指定されていないため負債が不完全
  • ベースラインでコード カバレッジ データが利用できません
    コードカバレッジが現在の分析結果では利用可能だが、ベースライン分析結果では利用できない場合、コードカバレッジに関連するルールは問題を生成しません。実際、この状況ではカバレッジの問題をベースラインで推定できず、すべてのカバレッジの問題が新しい問題として表示されてしまいます。
    この状況は、プロジェクトが作成され、最初に取得された分析結果にカバレッジデータが含まれていない場合によく発生します。CppDepend プロジェクトでは、既定のベースライン設定は、次に最も近いベースライン分析結果を選択することです 30日前に取得、この問題は1か月続く可能性があります。
    通常 この状況を修正するには、コードカバレッジデータを持たない履歴分析結果を削除することをお勧めします。そのためには、次で定義された履歴分析結果を含むフォルダーを開く必要があります CppDepend プロジェクト プロパティ > Analysis > Baseline for Comparison > Historic Analysis Results (既定ではプロジェクトの出力フォルダーに設定)。次に、削除する履歴分析結果を含むフォルダーを特定し、そのフォルダーを削除します。
    たとえば、下のスクリーンショットでは、選択されたフォルダーは 2016 年 12 月 13 日午前 8 時 59 分に取得された履歴分析結果を表しています。
    ベースラインにカバレッジ日付がありません
    この手動のフォルダー操作は、そのような状況を解決する最適な方法ではないことを理解しています。履歴分析結果を一覧表示し、カバレッジデータのないもの(ソースコードが解決されないなどの他の欠陥)を表示し、それらを削除できる UI の提供をご希望の場合は、お知らせください。
    分析時に、特定の基準(カバレッジデータが利用可能など)を満たさない分析結果を履歴として保存しないフィルターを提供することもできます。

今すぐCppDependを試す

ドキュメントの全機能にアクセスできる14日間無料トライアル。クレジットカード不要。