2012-01-06 10 views
1

私のドメインにはランダムに決定された選択が含まれており、単体テスト方法はわかりません。ランダムな選択肢をテストするにはどうすればよいですか?

些細な例として、私はそのmyobject.makeChoice()戻り、時間のtrue 75%と時間のfalse 25%を確保したいとしましょう。どのように私はこれをユニットテストすることができますか?

  1. 私はmyobject.getChoiceAPercent()が75であることを主張することができ、それは実際の結果をテストしていないので、その は、些細な有用ではない、と満足できないようです。

  2. 私はmyobject.makeChoice()千回実行し、それが は時間のtrue 70%〜80%パーセント、またはそのようないくつかの統計 方法を返しますが、そのそれは、壊れやすい遅い、と 不十分なようだと主張することができます。

  3. Iが所定の乱数発生器又は ランダムシードとユニットテストを実行し、そのmakeChoice()ランを5回アサートすることができ、例えば、 [true, true, false, true, true]を返し、それはそのランダム(123)== 456をアサートするよう 同じですそして、私は実際のドメインをテストすることはないので、また、私が興味不十分なようだ。

ランダムな選択は乱数発生器自体ではなく、ユニットテストの帰納的推論で正しい証明できるようです。ランダムに生成されたコンテンツは、自動テストに適していないか、私が気付いていない簡単な方法がありますか?

[編集]のは、次の実装を想定してみましょう、など「ランダム擬似」対「真のランダム」をめぐる紛争を避けるために:

public boolean makeChoice() { 
    return this.random.nextDouble() < 0.75; 
} 

私はユニットテストのmakeChoice戻りtrue約75%ということにはどうすればよいです時間?

+0

私は混乱しています。ランダムであれば、定義によって無作為にすることなく、75%と25%にとどまるように動かす方法はありません。 – Andy

+0

質問を明確にする実装を追加しました。 –

+0

別の質問があります。あなたのコードは真実を返すはずです。空間の75%、私は1000チャンスで750個のtruesを返さなければなりません。あるいは100チャンスで75を返します。 –

答えて

0

ランダム性のテストはランダムには見えません。しかし、一意性/衝突をテストするために、私は通常、ハッシュ構造を使用し、ランダム値をキーとして挿入します。重複したキーは上書きされます。一意のキーの最終的な数と反復の総数を数えることによって、アルゴリズムの一意性を「テスト」することができます。

+0

私は一意性に関心がありません、私はランダム性に懸念しています。この単純な例には2つの選択肢しかないので、一意性は役に立たないようです。重複の代わりに重複を数えた場合、これはソリューション#2と同じです:一度に複数回実行し、平均的にはあなたが期待していると主張します。 –

+0

@TrystanSpangler - 基本的に私はあなたのソリューション#2に同意します。これらの2つの選択肢のそれぞれを無作為に選んだ回数を推定する反復テストを実行することで、あなたのためらいがあるかどうかはわかりません。 –

+0

私はTim Medoraに同意します。 2番は論理的な選択のように聞こえる。あなたが必要とする選択肢と一致する可能性のあるチャンスのために、それを一定の時間だけ行うだけです。それぞれの選択肢の中には、それが真実か偽であるかを示すカウンターがあり、それが80%だったのと比較して20%などでした。 – Andy

0

あなたのコードは、RNGから分離されていません。おそらく、次のように書くことができます:

public boolean makeChoice(double randnum) { 
    return randnum < 0.75; 
} 

そして、実装をテストするためにキー値をテストします。

またはランダムオブジェクトを特定のシードに初期化することができます。このシードは、[0、1]の間に既知の乱数を与え、既知の数字で起こると予想されるものに対してテストします。

また、IRandomを定義して、インタフェースを実装するRandomのフロントを記述し、プログラムで使用することもできます。次に、数字0.00、0.01、0.02 ...、0.99、1.00を順番に与えるモックIRandomでテストし、成功回数を数えます。

0

コードのランダム性をテストしないで、乱数ストアの値を渡すか値を取得してランダム性の結果をテストします。

単体テストのカバレッジを100%得るのはいい目標ですが、リターンを減らす法則です。あなたはPRNGを書きましたか?

編集:How do you test that something is random? Or "random enough'?

0

私は第二の「デカップリング」の戦略:それは良いリンクのカップルを持っているとしても、この答えをチェックしてください。私は、ランダムな値や時間に依存するものは、それを決定論的に「さらに別の依存関係」からの「もう一つの入力」として扱うべきだと思っています。次に、書くか信頼するクロック、つまりRNGを注入します。

たとえば、あなたのケースでは、「選択」が時間の75%ではなく80%であれば、実際には異なる動作をしますか?私はあなたのコードの大部分が選択が真実か間違っているかどうかを気にしていると思うし、もう一つは選択をするものだと思う。

これはランダムジェネレータをどのようにテストするかという問題を引き起こします。その場合、「偉大な数」のルール、いくつかの近似、数学に頼って、単純にrand()を信頼するのが良い方法です。

0

それはランダムなブール値ですので、2つのテスト(TRUEに1つ、FALSEに1つ)を記述することはかの行動は、過去「ランダム」の結果に依存しないだけで十分かもしれません(それは、少なくとも私には、明確ではありませんが、質問から)。

つまり、連続する結果が互いに依存しない場合は、単一のTRUEシナリオ、つまりFALSEシナリオをテストしても問題ありません。

関連する問題