パラメータ化されたテスト-いつ、なぜそれらを使用しますか?


15

最近仕事では、パラメータ化テストに関して意見の違いがあります。通常、TDDスタイルを使用します(少なくとも試してみます)。そのため、このアプローチの利点を理解しています。ただし、パラメータ化されたテストがもたらすゲインの表示に苦労しています。参考のために、RESTfulインターフェースを介して公開されるサービスとそのライブラリーに取り組みます。

これまで見てきたのは、少なくともEclipse内でJUnitを使用するテストです。

  • 詳細がない-テストが失敗すると、失敗の原因となったパラメーターを見ることは非常に困難です
  • 作成が複雑なことが多い
  • コードが記述された後に作成される傾向があります-厳密には欠点ではありませんが、コードを開始するときにパラメータ化されたテストを念頭に置いていますか?

誰かが本当に便利な場所の例や、それらを使用するための良いヒントさえあれば素晴らしいでしょう。私は個人的にそれらを使用することを選択しないので、私が頑固ではないことを確認したいと思います。


1
問題はアイデアにあるのではなく、不格好なライブラリにあります。C#では、say MbUnitを使用すると、構文がより使いやすくなります。はい、それは良い考えです。独自のコードを追加して、このプロセスを簡単にします-ファイルからものを読み取ります-何でも動作します。MsTestがこれをどのように処理するかも見てください。
ジョブ

私たち(Square)は、これらの問題のいくつかに対処するためにBurstを作成しましたParameterized。通常、追加する定型文が少なくなり、テストが失敗した場所がかなり明確になります。
ダニエルルバロフ14年

回答:


4

ソフトウェアの一部をテストする際の問題は、複雑さが急速に爆発することです。実際、メソッドに渡されるパラメーターの可能な組み合わせをすべてテストすることはできませんPhadkeは、実験計画(DOE)アプローチを提唱しています。これにより、テストが必要なパラメーター値のリストを生成できます。

その考えは、徹底的にテストしていなくても、ほとんどの欠陥が孤立点故障ではなく「故障領域」を発生させるというものです。直交配列を使用するDOEのアプローチは、可能性のあるすべてのフォールト領域にヒットするのに十分なほどパラメータースペースをサンプリングします。

孤立した障害はおそらく識別されませんが、これらは一般に障害領域よりも少ないです。

DOEアプローチでは、変化させるパラメーター値を体系的に選択できます。


提供されたリンクが壊れています。
ジョシュガスト

1
@JoshGust Googleを使用して簡単に修正できます。ヘッドアップをありがとう。
ピーターK.

4

これらは、コードがハッピーパスだけでなくエッジケースも処理することを保証するのに役立ちます。コードが通常の変数で機能することを確認したら、テストケースをパラメーター化し、nullと0、空の文字列、大きな数字、長い文字列、奇妙なUnicode文字なども正常に機能することを確認します。


2

少なくともJUnit 4.8には、少なくとも2つのパラメーター化されたテストがあります。パラメーター化されたテスト(@RunWith(Parameterized.class))は、定義済みのパラメーター構成を生成/読み取るデータソースを必要とします。理論(@RunWith(Theories.class))は、引数の型ごとに1つ以上の可能な入力セットを指定したメソッドの仕様を実行できます。次のように見えます:

  • @DataPoints文字列引数にいくつかの可能な値()を指定します(null空の文字列、空でない文字列、本当に長い文字列など)
  • @DataPointsAnimalクラスの引数(nullDogインスタンス、Catインスタンス、Birdインスタンスなど)に可能な値()を指定します
  • パラメータとパラメータ@Theoryを受け入れるprepare 。可能なパラメーター値のあらゆる可能な組み合わせで実行されます(与えられた例では、(、)を含む4x4 = 16の組み合わせになります)StringAnimalnullnull
  • テスト中のメソッドがいくつかの組み合わせを受け入れられない場合、Assume.assumeThat静的インポートを使用して無効な組み合わせを除外します(たとえば、空でない文字列のメソッドの動作を確認する場合、最初の行の1つは「nullではないと仮定する」

前に書いたように、すべてのメソッドのあらゆる組み合わせをテストすることは意味がありません(テストセットを爆発させ、5つのパラメーターでメソッドをテストすることを想像してください。 !)、ただし、ミッションクリティカルなメソッド(APIメソッドなど)の場合は、念のために推奨します...


1

一般的な例:

  • 文字列引数を持つメソッド。パラメーター化されたテストを使用して、さまざまな入力とそれらの期待される出力をテストします。ペアごとにTCを記述するよりも、ペアのリスト(入力、予想)を使用する方がはるかに実用的です。

  • 同じシナリオを異なる引数に適用します。私たちは、と連携シナリオ持つAnimalオブジェクトをとのようなサブクラスの多くを持ってDogCatBird。利用可能な動物のリストを作成し、それらのシナリオをテストします。

Webサービス用のコンクリート:

  • 上記の文字列引数の例から。同じ型で異なる値の異なる引数で何が起こるかをテストします。

0

パラメータ化されたテストは、さまざまな入力をテストするときに、単純な入力を持つ関数/機能のテストに適しています。

異なる機能や複雑な入力をテストするためにはうまく機能しません。より少ないコードを書くための便利な構造として使用すべきではありません。


1
なぜより少ないコードを書くための便利さとしてパラメーターを使用すべきではないのですか?テストケースの大規模な(ish)セットの完全なリストを提供することには大きな美徳はありません。
ジョナサンユニス

1
あなたの答えは、他の5つの答えよりも多くの情報をどのように提供しますか?
アダムザッカーマン

-2

多くのパラメーター化されたテストをTDD風に使用する1つのケースは、パーサーを書くことです-入力と期待される出力のリストから始めて、すべてのテストケースに合格するようにコードを書くことができます。

しかし、パラメータ化されたテストのいくつかの恐怖を見てきました。いいえ、バージニア州、あなたのテストスイートはそれ自身のユニットテストである必要はありません。


1
理想的には、パラメータ化されたテストは、「実際の出力でitem(n)が期待出力でitem(n)に一致する」などの形式である必要があります。その場合、テストは不要です。しかし、もっと複雑なものについては、通常の手を振る「私の(テスト)コードは明らかに正しい」よりも、きれいなパラメーター化されたテストを独自のテストケースで見たいと思います。それが本当なら、テストケースをまったく書いていません。明らかに、複雑さを乗り越えてしまう可能性があり、線がないと主張しているわけではありませんが、テストをテストすることは良い考えだと思います。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.