2016-09-06 19 views
5

FsCheckを使用してF#でいくつかのプロパティテストを行っています。したがって、私は、入力引数にかかわらず、一定の条件が常に成立することを保証したいと考えています。F#のナノ値に対するプロパティテストの簡潔で一般的な方法は何ですか?

私はfloatの値に対して簡単な同一性関数を定義することを考えてください。

let floatId (x : float) = x 

私はその後、私は常に保持する必要があります知っているこの機能のテスト定義:これは些細なテストです

let ``floatId returns input float`` x = floatId x = x 

を、私はちょうど私のフロート恒等関数を呼び出すことと同じように返すかどうかを確認しています入力フロート。

私はその後FsCheckにこの機能をプラグ:

Check.Quick ``floatId returns input float`` 

残念ながら、このプロパティのテストが失敗しました!もちろん

Falsifiable, after 21 tests (0 shrinks) (StdGen (1872424299,296201373)): 
Original: 
nan 

、振り返ってみると、我々がnan <> nanことを知って、これが起こるとしていたかなり明白でした。

F#で構造を比較しているため、コレクションを含む(さらに)複雑なテストケースに悩まされる可能性があります。

私はフロートリストに同様の機能を設計する場合:

let listFloatId (lst : float list) = lst 

let ``listFloatId returns input float list`` lst = listFloatId lst = lst 
Falsifiable, after 6 tests (3 shrinks) (StdGen (1874889363,296201373)): 
Original: 
[nan; 2.0; 2.25; 4.940656458e-324] 
Shrunk: 
[nan] 

同じ問題をもう一度!


もちろん、私は自分の平等のテスト関数を作成することで、この問題を回避エンジニアリングすることができ、それはfloat値の罰金ですが、私は私のカスタム平等機能付きList.forall2を使用して開始する必要があるため、それはlistのようなコレクションに拡張するために、より複雑になり、一般的に私のコードを個々のコレクションタイプに特化しています。

F#でこの問題を解決する一般的な方法はありますか?

+1

私はおそらく私がよく記録に知られているように見えていない一つの可能​​な解決策を置くためにこれをやっている@JohnPalmerナン –

+0

考慮して平等をしましたnew演算子でこれを解決するだろう。確かに他の人を聞いて興味があると思います。 – TheInnerLight

+0

ああ - あなたはすでにこのための答えを持っていた実現しなかった - その関数は何が必要である基本的に同じように見えます。 –

答えて

5

LanguagePrimitives.GenericEqualityER機能を使用してこの問題を解決できます。これは、等価関係セマンティクスを使用して等価性をチェックします。この関数は、実際には[nan]のリストを比較する具体的な例を掲載しています。

テストケースは次のように定義することができます:上記のプロパティがで育ったので、(私は、この質問をし、答えています

Ok, passed 100 tests. 
Ok, passed 100 tests. 

let ``ER : floatId returns input float`` x = LanguagePrimitives.GenericEqualityER (floatId x) x 

let ``ER : listFloatId returns input float list`` lst = LanguagePrimitives.GenericEqualityER (listFloatId lst) lst 

この時間FSharp Software Foundationのスラックチャンネルと私は、この解決策を記録しておくと便利だと思いました。私はLanguagePrimitivesモジュールのドキュメント)を超えてオンラインこの機能のほとんど言及を見つけることができます。

関連する問題