.NET Tools
テスト・シナリオを自動生成できる
(株)ピーデー
川俣 晶 |
|
|
静的解析と動的解析
.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」 |
- 第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用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|