.NET Tools

テスト・シナリオを自動生成できる
テスト・ツール「.TEST」(ドットテスト)

(株)ピーデー 川俣 晶
2004/02/04
Page1 Page2 Page3

静的解析と動的解析

 .TESTを用いてプログラムの品質を上げたいと思うなら、まず最初に.TESTがやってくれる作業が具体的に何であるかを正しく理解する必要がある。

 .TESTが行う作業は、主に「静的解析」と「動的解析」に分けられる(前項で行った「完全解析」はこれら2つの組み合わせである)。静的解析は、実際にプログラムを実行することなく、ソース・コードを調べてコーディング上の問題点をレポートする機能である。「.NET Framework Design Guidelines」*1より抽出した約200個のコーディング・ルールを持っているとしている。これは、具体的にバグを発見するというよりも、バグになり得る可能性を持ったコードを検出する機能と思えばよいだろう。そのような性格上、個々のルールの中には、適用することが不適切なものもある。そのため、ルールを使うか否かは選択できる。また、検出するルールは、「RuleWizard機能」で新規に作成することができる(これについては後で紹介している)。

*1 これはリファレンス・マニュアルにある「クラス ライブラリ開発者向けのデザイン ガイドライン」に相当する。

 静的解析でチェックされるルールの一例として、「大文字と小文字を区別しないパラメータ名(NFDG.CSN-2)」がある。これは「大文字・小文字の違いしかない同じ名前のパラメータを使って関数を作成してはいけません」という指摘だが、大文字・小文字を区別するプログラム言語(C#など)と区別しないプログラム言語(VB.NETなど)があるため、言語間の相互運用性を確保するために必要なルールである。

 静的解析に対して、動的解析は、実際にプログラムを実行することでテストを行う。実行は、メソッドなどを単位にして行う。個々のメソッドには、さまざまな事前条件、Outcome(期待される結果)、事後条件、などを設定した複数のシナリオを用意し、これらを自動的に実行してレポートを作成する。

 シナリオは以下のような形で設定されている。

自動生成されたシナリオを編集するためのシナリオ・エディタ
動的解析のためのシナリオでは、さまざまな事前条件、Outcome(期待される結果)、事後条件などが自動生成される。シナリオ・エディタは[動的解析]タブの[編集]ボタンから起動でき、シナリオの詳細を編集できる。

 ここでは、Addメソッドの事前条件として各引数の値が指定され、Outcomeとしてリターン値が指定され、事後条件として引数の値が変化しないことが指定されている。

シナリオの自動生成の存在意義

 ここで注意を払う必要があるのは、静的解析はすでに用意された多数のコーディング・ルールによって、すぐにでも意味のある解析が可能であるのに対して、動的解析はシナリオを用意することなく実行することができない点である。もちろん、メソッドの仕様は個々のメソッドごとに異なるので、最初からシナリオを組み込んでおくことはできない。つまり、動的解析を行うなら、シナリオを作成する手順を避けることはできず、それには多大な手間を要するということである。

 このような問題に対処するために、.TESTではシナリオの自動生成機能が用意されている。これは、指定されたアセンブリ(実行ファイル)に含まれるメソッドなどに対して、さまざまな引数のバリエーションを指定するシナリオを自動生成するものである。使用される引数の値も、よく問題を引き起こすといわれる最大値、最小値、0(ゼロ)などを指定した複数のシナリオが生成される。これによって、網羅的な膨大な数のシナリオが生成でき、それらを一気に実行することができる。

 しかし、自動生成されたシナリオは、品質をチェックするという意味では、それだけでは何の価値もないことに注意をしなければならない。それは、期待される結果がなぜ自動生成できるかを考えれば分かるだろう。あるメソッドの処理結果が正しいかどうか、ソース・コードを調べるだけで判定するのは無理というものだ。それは、ちょっと考えればすぐ分かることだろう。あるメソッドに-1と1を渡したときに、戻り値が0になるべき根拠は、メソッドの仕様書に書かれているものであって、ソース・コードに書かれているべきものではないからだ。メソッドの仕様書がない場合は、プログラマの頭の中にしかないかもしれない。それを、たかだかコンピュータ・プログラムが読み取って正しいシナリオを作成することなど、できるはずもない。自動生成されるシナリオに含まれる結果は、自動生成された引数を指定してそのメソッドを呼び出した結果を「期待される結果」として書き込んでいるにすぎないのである。

 それでは何の意味もないどころか、インチキだ! と思った人もいるかもしれない。だが、そう決めつけるのは早計である。このように生成されたシナリオには、2つの利用方法があるからだ。

 最初の利用方法は、シナリオのチェックを通してバグを見つけ出すことである。シナリオは、問題を起こしやすい値を引数に指定して実際にメソッドを実行した結果を記録している。ということは、普通にプログラムを実行して試しているだけではなかなか遭遇しないケースばかりが、ずらっと並んだリストが手に入るということである。つまり、シナリオをチェックしていくだけで、問題を起こしやすいケースのメソッドなどの妥当性をまとめてチェックできるということである。チェックの結果、意図しない値が期待される結果として書き込まれたシナリオがあれば、それはそのメソッドにバグがあるということを示すことになる。これと同じ作業を.TESTを用いずにやるなら、何倍もの時間と労力を必要とすることだろう。

 2番目の利用方法は、ソース・コードを書き換えた結果の保証である。世の中には、動いているコードには手を触れるな、というルールがある。エクストリーム・プログラミングなどでは、変化を包容せよと称して、ソース・コードを書き換えることを推奨しているが、これは書き換えのリスクを軽減するための手順を別途用意するから可能になることである。普通は、動いているコードを書き換えるべきではないというルールが成立する。しかし、書き換えたくなくても、書き換える必要が発生してしまうこともある。そういう場合に、.TESTが自動生成したシナリオが役に立つ。ソース・コードを書き換える前に、シナリオを自動生成しておき、それがすべてパスするようにしておく。そして、ソース・コードを書き換えた後で、そのシナリオで動的解析を行う。すると、もしソース・コードを書き換えた結果、挙動が違っていれば、それが即座に分かるのである。もし、変わってはならない結果が変わっていれば、それはソース・コードの書き換えに誤りがあったということになる。このような問題を、.TESTでは非常に簡単に検出することができる。

静的解析ルール

 ビルドインされた静的解析ルールの一覧にほぼ対応するものが、すでに紹介した「Active static rules」(生成されたドキュメントの1つ)で見ることができる。

 これらの主要な分類とルール数を以下に示す。

名前付けのガイドライン
大文字と小文字の区別
5個
インターフェイスの名前付け
2個
大文字の使用のスタイル
28個
属性の名前付け
1個
単語の選択
16個
列挙型の名前付け
4個
略語
33個
静的フィールドの名前付け
2個
型名の混乱の回避
13個
パラメータの名前付け
2個
名前空間の名前付け
2個
プロパティの名前付け
2個
クラスの名前付け
5個
イベントの名前付け
6個
 
クラスメンバの使用のガイドライン
プロパティの使用
11個
コンストラクタの使用
6個
イベントの使用
7個
フィールドの使用
6個
メソッドの使用
7個
 
型の使用のガイドライン
基本クラスの使用
3個
列挙の使用
6個
Sealedクラスの使用
2個
属性
4個
構造体の使用
2個
ネストされた型の使用
1個
 
COMのガイドライン
5個
エラーの発生と処理
4個
配列の使用のガイドライン
2個
演算子のオーバーロードの使用ガイドライン
13個
型キャストのガイドライン
2個
共通のデザイン・パターン
12個
静的解析ルールの種類と個数

 ここでは、もう少し詳しく静的解析ルールについて説明しよう。

 静的解析ルールは、.TEST本体で[静的解析]タブをクリックすることで、種類ごとに分類されたツリー構造で見ることができる。

静的解析ルールのツリー表示
.TESTで[静的解析]タブをクリックすると表示される。チェックの付いたルールが静的解析の実行時に適用される。

 個々の項目に付いたチェック・ボックスのチェックを外すことで、静的解析の対象から外すことができる。また詳しい内容は、項目名を右クリックして「ルールの説明を表示」を選ぶことで知ることができる。例えば、「分野が異なる型のキャストは避ける」なら、以下のように表示される。

静的解析ルールの詳細情報
静的解析ルールのツリー表示時にルールを右クリックして「ルールの説明を表示」を選ぶと表示される。

 さて、静的解析ルールのツリー表示で、それぞれの名前の前に付いている「SV」のような文字(カテゴリ)には、以下のような意味がある。

カテゴリ
カテゴリの意味 概要
I
通知(Informational) 参考情報。バグを引き起こす可能性が最も低いエラーのカテゴリ
PV
発生するかもしれないルール違反(Possible Violation) スタンダード・コーディングにおいて違反になる可能性のあるルールを表すカテゴリ
V
ルール違反(Violation) コーディング・スタンダードにおいて違反になるルールを表すカテゴリ
PSV
発生するかもしれない深刻なルール違反(Possible Severe Violation) コーディング・スタンダードにおいて重大な違反になる可能性があるルールを表すカテゴリ
SV
深刻なルール違反(Severe Violation) コーディング・スタンダードにおいて重大な違反のルール。バグを引き起こす可能性が最も高いエラーのカテゴリ
静的解析ルールのカテゴリとその意味

 これらの重要度の分類によって表示する対象を絞ったり、対処する手順の優先順位を付けたりすることができる。


 INDEX
  [.NET Tools]
  テスト・シナリオを自動生成できるテスト・ツール「.TEST」(ドットテスト)
     1..TESTによるドキュメント生成の実際
   2.静的解析と動的解析、シナリオの自動生成の存在意義
     3.RuleWizard、メソッドの動的解析、テスト駆動開発との対比
 
インデックス・ページヘ  「.NET Tools」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間