4

私は当初、最初の 5 つの要素が修正されたジェネレーターを作成しようとしましたが (Prop.forAll最初の 5 つを使用するテストでは常に実行されます)、失敗しました。

現在、範囲内のランダムデータ用に1つのジェネレーターと、非ランダムデータ用に1つのジェネレーター、つまり固定シーケンスを使用することで、これを簡素化しようとしています。に似てGen.constantいますが、1 つの値ではなく一連の値である点が異なります。

私はこれを持っています(単純化された再現可能な例、NUnitとxUnitで動作します):

[<Property(Verbose = true, MaxTest=5)>]
static member MultiplyIdentityCornerCases () =
    Gen.elements [0L; -1L; 1L; Int64.MinValue; Int64.MaxValue]
    |> Arb.fromGen 
    |> Prop.forAll <| fun x -> x = x * 1L

出力は次のとおりです(どこからnull来たのかわかりません):

0:
<null>
9223372036854775807L
1:
<null>
-9223372036854775807L
2:
<null>
-9223372036854775807L
3:
<null>
1L
4:
<null>
-9223372036854775807L
Ok, passed 5 tests.

出力には、5 つのテストすべてを順番に、できれば順序どおりに含めたいと思います。testdata プロバイダーを使用して NUnit (または任意の単体テスト システム) でこれを実行できることはわかっていますが、FsCheck で実行できるかどうか (または、そうすべきかどうか、おそらくこれは悪い考えです) を考えています。

FsCheck を使用すると便利だと思います。関数の引数が複数ある状況では、与えられたコーナー ケースの引数のすべての組み合わせを徹底的にテストする必要があります。これは、testdata プロバイダーよりも FsCheck の方が簡単であることが期待されます。

4

1 に答える 1

7

それが可能かどうかはわかりませんが、これを行うことができます:

open System
open FsCheck
open FsCheck.Xunit

[<Property>]
let MultiplyIdentityCornerCases () =
    Gen.oneof [
        Gen.elements [Int64.MinValue; -1L; 0L; 1L; Int64.MaxValue]
        Arb.generate ]
    |> Arb.fromGen
    |> Prop.forAll <| fun x -> x = x * 1L

には 2 つのジェネレータが渡されるGen.oneofため、それぞれが約半分の値を生成します。

Gen.elements提供されたシーケンス内のすべての値から均一に選択する必要があるため、たとえば0L20% の時間を使用しますが、 を使用する場合はその半分のみをGen.oneof使用しますGen.elements

つまり、これらの「特別な」値はそれぞれ 50% * 20% = 10% の確率で生成されます。

デフォルトでは、プロパティは 100 個のテスト ケースを実行するため、平均して 10 個0Lの値、10 個の値などを生成する必要がInt64.MinValueあります。多くの場合、それで十分です。


そうでない場合は、いつでも次のようなことができます。

open System
open Xunit
open FsCheck
open FsCheck.Xunit
open Swensen.Unquote

[<Theory>]
[<InlineData(Int64.MinValue)>]
[<InlineData(-1L)>]
[<InlineData( 0L)>]
[<InlineData( 1L)>]
[<InlineData(Int64.MaxValue)>]
let MultiplyIdentityCornerCases x = x =! x * 1L

[<Property>]
let MultiplyIdentityCornerCasesProperty x =
    MultiplyIdentityCornerCases x

ここでは、xUnit.net の[<Theory>]機能を使用してパラメーター化されたテストを定義し、関心のある 5 つのコーナー ケースをフィードします。テストを実行すると、テスト ランナーはこれら 5 つのテスト ケースを実行します。

さらに、 でMultiplyIdentityCornerCasesProperty注釈が付けられているため実行され[<Property>]、その関数は単に他の関数を呼び出します。

于 2016-12-09T18:26:49.270 に答える