164

フィールドにランダムデータを入力するオブジェクトの単体テストを作成する同僚がいます。彼の理由は、通常のテストでは単一の静的な値しか使用しないのに対し、多くの異なる値をテストするため、テストの範囲が広がるためです。

私は彼にこれに対していくつかの異なる理由を与えました、主な理由は次のとおりです:

  • ランダムな値は、テストが本当に再現可能ではないことを意味します(つまり、テストがランダムに失敗する可能性がある場合は、ビルドサーバーで失敗し、ビルドを中断する可能性があります)
  • ランダムな値でテストが失敗した場合は、a)オブジェクトを修正し、b)毎回その値をテストするように強制する必要があります。これにより、動作することがわかりますが、ランダムであるため、値が何であるかはわかりません。

別の同僚が追加しました:

  • 例外をテストしている場合、ランダムな値では、テストが期待どおりの状態になることは保証されません。
  • ランダムデータは、単体テストではなく、システムのフラッシュと負荷テストに使用されます

他の誰かが私が彼にこれをやめさせるために彼に与えることができる追加の理由を追加できますか?

(または、これは単体テストを作成するための許容可能な方法であり、私と他の同僚は間違っていますか?)

4

19 に答える 19

81

妥協があります。あなたの同僚は実際に何かに夢中になっていますが、私は彼のやり方が間違っていると思います. 完全にランダムなテストが非常に役立つかどうかはわかりませんが、無効ではないことは確かです。

プログラム (またはユニット) 仕様は、それを満たすプログラムが存在するという仮説です。プログラム自体は、その仮説の証拠です。単体テストとは、プログラムが仕様に従って動作することを反証するための反証を提供する試みです。

単体テストを手動で記述できるようになりましたが、これは実際には機械的な作業です。自動化することができます。あなたがしなければならないのは仕様を書くことだけで、マシンはあなたのコードを壊そうとするたくさんの単体テストを生成することができます.

使用している言語はわかりませんが、こちらを参照してください。

Java http://functionaljava.org/

Scala (または Java) http://github.com/rickynils/scalacheck

Haskell http://www.cs.chalmers.se/~rjmh/QuickCheck/

.NET: http://blogs.msdn.com/dsyme/archive/2008/08/09/fscheck-0-2.aspx

これらのツールは、整形式の仕様を入力として受け取り、自動生成されたデータを使用して、必要な数の単体テストを自動的に生成します。彼らは「縮小」戦略 (微調整可能) を使用して、コードを壊すための最も単純なテスト ケースを見つけ、それがエッジ ケースを適切にカバーするようにします。

ハッピーテスト!

于 2008-08-28T15:46:31.963 に答える
47

この種のテストは、モンキーテストと呼ばれます。正しく行われると、それは本当に暗い隅からバグを吸い出すことができます。

再現性に関する懸念に対処するには、これに取り組む正しい方法は、失敗したテストエントリを記録し、特定のバグのファミリ全体をプローブする単体テストを生成することです。そして、最初の失敗を引き起こした(ランダムデータからの)1つの特定の入力を単体テストに含めます。

于 2008-09-18T01:21:08.017 に答える
28

ここには、PRNG に定数をシードするという用途のある中途半端な家があります。これにより、繰り返し可能な「ランダム」データを生成できます。

個人的には、(一定の) ランダム データがテストに役立つ場所があると思います。慎重に考え抜かれたコーナーをすべて実行したと思った後、PRNG からの刺激を使用すると、別のことがわかる場合があります。

于 2008-08-28T15:09:04.613 に答える
18

Beautiful Codeという本には、「Beautiful Tests」という章があり、二分探索アルゴリズムのテスト戦略について説明しています。1 つの段落は「Random Acts of Testing」と呼ばれ、ランダムな配列を作成してアルゴリズムを徹底的にテストします。この内容の一部は Google ブックスの95 ページでオンラインで読むことができますが、入手する価値のある優れた本です。

したがって、基本的にこれは、テスト用のランダム データの生成が実行可能なオプションであることを示しています。

于 2008-08-28T15:12:04.357 に答える
12

あなたの同僚はファジングテストを行っていますが、彼はそれについて知りません。これらはサーバーシステムで特に価値があります。

于 2009-03-13T05:46:32.797 に答える
12

テストを見ている人にとっての利点の 1 つは、任意のデータが明らかに重要ではないということです。何十個ものデータが関係する非常に多くのテストを見てきました。たとえば、住所検証方法が特定の郵便番号でテストされ、他のすべてのデータがランダムである場合、重要な部分は郵便番号だけであると確信できます。

于 2010-12-20T17:10:01.360 に答える
9
  • それがランダムな値でテストが失敗した場合、a) オブジェクトを修正し、b) 毎回その値を強制的にテストする必要があるため、それが機能することはわかっていますが、ランダムであるため、値が何であったかはわかりません。

テスト ケースにテスト内容が正確に記録されていない場合は、おそらくテスト ケースを再コーディングする必要があります。静的データまたはランダム データのどちらを使用しているかにかかわらず、テスト ケースが失敗した原因を正確に把握できるように、テスト ケースで参照できるログを常に保持したいと考えています。

于 2008-08-28T14:57:55.217 に答える
4

ランダム データを 1 回 (つまり、テスト実行ごとに 1 回ではなく、1 回だけ) 生成し、その後のすべてのテストで使用できますか?

考えもしなかったケースをテストするためにランダムなデータを作成することの価値は確かにわかりますが、ランダムに合格または不合格になる可能性のある単体テストを持つことは悪いことです。

于 2008-08-28T14:55:05.457 に答える
3

テストにランダム入力を使用している場合は、値を確認できるように入力をログに記録する必要があります。このようにして、遭遇したエッジケースがある場合、それを再現するテストを作成できます。ランダム入力を使用しないのと同じ理由を人々から聞いたことがありますが、特定のテスト実行に使用された実際の値を理解すれば、それほど問題にはなりません。

「任意の」データの概念は、重要でないことを示す方法としても非常に役立ちます。目前のテストに関係のないノイズ データが大量にある場合に思い浮かぶ受け入れテストがいくつかあります。

于 2008-10-09T03:26:04.803 に答える
2

ここでの問題は、単体テストの目的がバグをキャッチすることではないことだと思います。目的は、コードを壊さずに変更できるようにすることです。したがって、ランダム ユニット テストがパイプラインで緑色の場合、コードが正しいパスに触れていないという理由だけで、コードが壊れていることをどうやって知るのでしょうか? これを行うことは私にとって非常識です。別の状況では、それらを統合テストとして実行するか、ビルドの一部としてではなく e2e を実行することができます。状況によっては、そのようにテストするためにアサートにコードのミラーが必要になるため、特定の目的のためだけに実行することもできます。実際のコードと同じくらい複雑なテスト スイートを用意することは、テストをまったく行わないようなものです。:p

于 2021-02-26T00:54:03.900 に答える
0

テストデータの問題に対する3つの解決策を想定できます。

  • 固定データでテストする
  • ランダムデータでテストする
  • ランダムデータを一度生成し、それを固定データとして使用します

上記のすべてを行うことをお勧めします。つまり、脳を使用して解決されたいくつかのエッジケースと、一度だけ生成するいくつかのランダム化されたデータの両方を使用して、繰り返し可能な単体テストを記述します。次に、同様に実行する一連のランダム化テストを作成します。

ランダム化されたテストは、繰り返し可能なテストが見逃しているものを捕らえることを決して期待されるべきではありません。繰り返し可能なテストですべてをカバーすることを目指し、ランダム化テストをボーナスと見なす必要があります。彼らが何かを見つけた場合、それはあなたが合理的に予測できなかったものでなければなりません。本当の奇妙なボール。

于 2011-10-26T16:32:11.473 に答える
0

今日、これに遭遇しました。疑似乱数が必要でした (そのため、圧縮されたオーディオ データのように見えます)。私も deterministic が欲しかったことを TODO しまし。rand() は、OSX と Linux では異なっていました。再シードしない限り、いつでも変更される可能性があります。そのため、決定論的でありながら疑似ランダムに変更しました。テストは、定型データを使用するのと同じくらい繰り返し可能です (ただし、より便利に記述されています)。

これは、コード パスを介したランダムなブルート フォースによるテストではありませんでした。それが違いです。依然として決定論的であり、再現性があり、実際の入力のように見えるデータを使用して、複雑なロジックのエッジ ケースで一連の興味深いチェックを実行します。まだ単体テスト。

それでも資格はランダムですか?ビールを飲みながら話しましょう。:-)

于 2008-09-18T01:15:41.757 に答える
0

オブジェクト/アプリによっては、負荷テストでランダム データが使用される場合があります。データの境界条件を明示的にテストするデータを使用することがより重要になると思います。

于 2008-08-28T14:51:06.807 に答える
0

私の経験では、単体テストとランダム化テストは分離する必要があります。単体テストは、あいまいなバグを見つけるだけでなく、いくつかのケースの正確性を確実にするのに役立ちます。とはいえ、ランダム化されたテストは有用であり、単体テストとは別に実行する必要がありますが、一連のランダム化された値をテストする必要があります。実行ごとに 1 つのランダムな値をテストするだけでは十分ではなく、十分なランダム化されたテストでもなく、真に有用な単体テストでもないと思わずにはいられません。

もう 1 つの側面は、テスト結果の検証です。ランダムな入力がある場合は、テスト内で期待される出力を計算する必要があります。これにより、テストされたロジックがある程度複製され、テストはテストされたコード自体の単なるミラーになります。テストには元のコードと同じエラーが含まれる可能性があるため、これではコードを十分にテストできません。

于 2022-01-25T09:29:20.657 に答える
-1

彼が修正したかどうかを確認できなかった場合、どうすればテストを再度実行できますか? つまり、テストの再現性が失われます。

テストでランダムなデータの負荷を投げかけることにはおそらく何らかの価値があると思いますが、他の回答で述べられているように、それは何よりも負荷テストの見出しに該当します。それはほとんど「希望によるテスト」の実践です。実際には、あなたの男は自分が何をテストしようとしているのかを単純に考えておらず、ランダム性が最終的に何らかの不可解なエラーをトラップすることを期待して、その思考の欠如を補っていると思います.

したがって、私が彼に対して使用する議論は、彼が怠け者だということです。別の言い方をすれば、彼がテストしようとしているものを理解するのに時間がかからない場合、それはおそらく彼が書いているコードを本当に理解していないことを示しています.

于 2008-08-28T22:02:54.743 に答える