.NET Tools
テスト・シナリオを自動生成できる
(株)ピーデー
川俣 晶 |
|
|
静的解析とRuleWizard
静的解析のルールは、ただ単にどのルールを使うかを選択するだけでなく、RuleWizardの機能によって修正や新規作成が可能である。
静的解析ルールの修正や新規作成を行う「RuleWizard」 |
ルールはツリー構造のノードの集合体としてグラフィカルに作成できる。 |
画面にあるように、ルールはツリー構造のノードの集合体としてグラフィカルに作成できる。ここに表示されているものは、「プロパティのアクセシビリティと、そのアクセサのアクセシビリティは同一でなければならない」というルールである。例えば、最も左側のInterface、Struct、Classという要素は、インターフェイス、構造体、クラスを対象とすることを示し、右のandが、隣のノードとの条件の関係を示す。つまり、この場合、両方のノードが同時に成立している場合を示す。そして、さらに右に向かって、メンバーのプロパティを対象とすることが示され、スコープはpublicであることが示されている。
静的解析を活用するポイントは、実際の状況に応じて、適切なルールを取捨選択、追加していくことにあるといえるだろう。決して、どこかに唯一の正解はなく、その場の状況に応じて対応する必要があるだろう。そのため、よくトラブルの原因になるパターンが出てきた場合は、それを登録していくと有効だろう。
外部リソースに依存するメソッドの動的解析
これまでの説明で、すでにお分かりと思うが、動的解析を行う際には、対象となるメソッドなどを実際に呼び出して実行させるわけである(これは.NET Frameworkのリフレクションと呼ばれる機能により可能)。実行した結果を知るには実行するしかないので当然のことなのだが、処理する内容によっては単独で実行されては困る場合がある。例えばファイルやデータベースにアクセスする機能であれば、.TESTがテスト用に用意した引数の内容が、ファイルやデータベースに書き込まれてしまう可能性がある。そのような意味のないデータがあると、正規のプログラムの実行に妨げになる場合もあるだろう。
このような状況に対処するために、.TESTでは「スタブ」という機能が用意されている、これはテスト対象のメソッドが呼び出すほかのメソッドを実際には呼び出さず、スタブと呼ばれるダミーのメソッドを呼び出す機能である。ダミーのメソッドを呼び出す機能のことを「セーフ・コール」と呼ぶ。
これを指定するには、プロジェクトのツリーからメソッドを選んでおいて、[動的解析]タブを選び、さらに[Stub]タブを選ぶ。そして、メソッド名の右側をダブルクリックすると、「オリジナル関数」と「セーフ・コール」を選択することができる。ここで「セーフ・コール」を選択すると、そのメソッドの呼び出しは、実際のメソッドではなく、あらかじめ.TEST側で用意されたセーフ・コール機能を呼び出すことになる。
[動的解析]内にある[Stub]タブ |
ここではテスト時のメソッド呼び出しを、実際のメソッドではなく、ダミーのメソッドであるスタブに切り替えることができる。スタブの呼び出しは、ここでは「セーフ・コール」と呼ばれている。 |
セーフ・コールが行われた場合は、それぞれの型に対して、以下の値が返される。
- Boolean型 : false
- Char型 : 'a'
- Int32型、Int64型など : 0
- Float型およびDouble型 : 1.0
- Objects型 : null
スタブを使う場合は、これらの値が返されても適切に動作するようにコーディングしておく必要がある。
■コラム レポートは確認して使う このルールの本来の意図は、すべてのメンバーが静的であって、インスタンス作成が無意味なクラスに対して、インスタンス作成を行うことができないようにすることである。無意味なインスタンスを作成しようとすると、コンパイラがエラーを報告して気付かせてくれるのである。しかし、VB.NETのモジュールはすべてが静的であるので、言語仕様的に書くことができないし、機能の趣旨からして書く意味もないものである。 もう1点、動的解析のレポートでいくつかの「fail」が記録されていることに気付いた読者もいるだろう。例えば「Add.4.scn」と名付けられた項目において、引数に2147483647と1をAddメソッドに渡している。この2つを加算すると、Integer(System.Int32)で表現できる範囲を超えてしまうので、OverflowException例外が発生し、これがfailとして記録されている。 しかし、これが常にバグを意味しているのかというと、そうではない。例えば、これが100点満点の試験の採点を行うプログラムで、得点の加算を行うプログラムの一部だったとすれば、得点が100を超えることはなく、Integer型がオーバーフローするほど大きな値を使うことはあり得ない。そのような状況では、オーバーフローが発生する場合に対する適切な対処が、メソッドの要件として求められていないかもしれない。しかし、そのような意図のすべてをプログラムが読み取れるわけもなく、.TESTでは「pass」とは見なさず、fail扱いとしている。そのようなわけで、自動生成した動的解析のシナリオは、常にパスするわけではなく、必要に応じてシナリオの確認と修正を必要とするのである。 |
テスト駆動開発との対比
自動化されたテスト・ツールということになると、テスト・ファーストやテスト駆動開発との関係が気になるところである(テスト駆動開発については別稿「『テスト駆動開発』はプログラマのストレスを軽減するか?」を参照)。しかし、これらとの関係はないと考えた方が分かりやすいだろう。むしろ、これらの開発技法とは正反対のベクトルを持ったツールであると考えるべきかもしれない。
例えば、テスト駆動開発であれば、メソッドを書き始める前に単体テストを書く。しかし、.TESTでは、存在しないメソッドのシナリオを作成することはできない。つまり、テスト駆動開発で行われるテスト作成→コーディング、という手順の作業はできない。まずコードがあって、そこからテストのためのシナリオを作成する手順となる。
また、テストの網羅性と、実行所要時間に対するスタンスも異なる。テスト駆動開発では、プログラマが重要だと思う条件のテストのみを用意し、あらゆるケースでのテストを網羅しない。それは、何回も繰り返し実行する高速性を獲得するためでもある。そのため、やや大きなプログラムのテストでも、1分程度で終わってしまったりする。
これに対して、.TESTのシナリオ自動生成は網羅的である。あらゆるメソッドのあらゆる引数に、最大値や最小値や0のような問題を起こしやすい特殊な値を入れたテストを生成する。あらゆる可能性を網羅しているために、シナリオの数は膨大になり、実行時間も長くなる。やや大きなプログラムでは、テストのフル実行に30分や1時間を要してしまうかもしれない。
このことから考えると、.TESTの想定する使い方が浮かび上がってくるだろう。.TESTは短いサイクルでテストを繰り返すために使われるべきものではなく、プロジェクトの節目節目に時間をかけて徹底的にテストを行うためのツールであるといえる。また、だれがテスト・ツールを使うのかという点も違っているだろう。テスト駆動開発ではプログラマがテストを行うが、.TESTは専任のテスト担当者がテストを行うと考えた方がよいだろう。
しかし、テスト駆動開発と.TESTの接点がない、というわけではない。残念ながら今回使用したバージョンではまだ機能しなかったが、NUnitのテスト・ケース生成というメニューが用意されている。NUnitはテスト駆動開発で使われる定番のテスティング・フレームワークだが(NUnitについては別稿「NUnit入門 Test Firstのススメ」を参照)、.TESTはNUnit用のテストを出力することもできる。この機能を使えば、両者のテストを1つのNUnit内でまとめて実行することも可能になるだろう。
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用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|