2015-09-27 43 views
12

私はビデオ解析用のコードをいくつか書いています。FsCheck in C#:同じ形状の2次元配列のリストを生成する

public class Video 
{ 
    public readonly int Width; 
    public readonly int Height; 
    public readonly List<int[,]> Frames; 

    public Video(int width, int height, IEnumerable<int[,]> frames) 
    { 
     Width = width; 
     Height = height; 
     Frames = new List<int[,]>(); 
     foreach (var frame in frames) 
     { 
      if (frame.GetLength(0) != height || frame.GetLength(1) != width) 
      { 
       throw new ArgumentException("Incorrect frames dimensions"); 
      } 
      Frames.Add(frame); 
     } 
    } 
} 

私はArbitrary<Video>を作成し、それを登録するにはどうすればよい:ここではVideoクラスの簡易版はありますか?どのように私はそれの任意のシュリンクャーを作るのですか?

これを試し
public static Arbitrary<Video> Videos() 
{ 
    var videoGen = Arb.Generate<PositiveInt>() 
     .SelectMany(w => Arb.Generate<PositiveInt>(), (w, h) => new {w, h}) 
     .Apply(/* what is Gen<Func<a,b>> */); 

    return videoGen.ToArbitrary(); 
} 

を、しかし、ここでは、リストのための発電機を差し込むことができませんでした:これを試し

は、作品を適用する方法を理解することができませんでした

public static Arbitrary<Video> Videos() 
{ 
    var videoGen = Arb.Generate<PositiveInt>() 
     .SelectMany(w => Arb.Generate<PositiveInt>(), (w, h) => new Video(w, h, /* how to plug generator here? */)); 

    return videoGen.ToArbitrary(); 
} 

答えて

12

Kurt Schelfthoutの答えを基礎として使用すると、任意のfo r videoクラスは次のようになります。

public static class VideoArbitrary 
{ 
    public static Arbitrary<Video> Videos() 
    { 
     var genVideo = from w in Arb.Generate<PositiveInt>() 
         from h in Arb.Generate<PositiveInt>() 
         from arrs in Gen.ListOf(
          Gen.Array2DOf<int>(
           h.Item, 
           w.Item, 
           Arb.Generate<int>())) 
         select new Video(w.Item, h.Item, arrs); 
     return genVideo.ToArbitrary(); 
    } 
} 

これはさまざまな方法で使用できます。あなたが好むどのプロセスでこれをホストすることができます:

プレーンバニラFsCheck

は、ここで必要とされていないxUnit.netテスト・ケース内にホストされているここでは、プレーンバニラFsCheckとビデオの任意の使用方法です

[Fact] 
public void VideoProperty() 
{ 
    var property = Prop.ForAll(
     VideoArbitrary.Videos(), 
     video => 
     { 
      // Test goes here... 
      Assert.NotNull(video); 
     }); 
    property.QuickCheckThrowOnFailure(); 
} 

Prop.ForAllは、カスタムArbitrariesとプロパティを定義するために非常に有用です。 QuickCheckThrowOnFailureに電話すると、Videoクラスの「すべて」(defailt:100)の値のテストが実行されます。

型なしxUnit.netプロパティ

またFsCheck.Xunitグルーライブラリを使用することができますが、属性に弱い型付けされた値として任意に合格する必要があります。

[Property(Arbitrary = new[] { typeof(VideoArbitrary) })] 
public void XunitPropertyWithWeaklyTypedArbitrary(Video video) 
{ 
    // Test goes here... 
    Assert.NotNull(video); 
} 

これは簡単です理解しやすいですが、そのArbitraryプロパティを割り当てるときに静的な型チェックが必要なわけではありませんので、私はこのアプローチをあまり好んでいません。カスタムArbitrariesでFsCheck.Xunitを使用する

型付きxUnit.netプロパティ

良い方法はcombine it with Prop.ForAllにある:このメソッドの戻り値の型はもはやvoidが、Propertyであること

[Property] 
public Property XUnitPropertyWithStronglyTypedArbitrary() 
{ 
    return Prop.ForAll(
     VideoArbitrary.Videos(), 
     video => 
     { 
      // Test goes here... 
      Assert.NotNull(video); 
     }); 
} 

お知らせ; [Property]属性はこの型を認識し、それに応じてテストを実行します。

この3番目のオプションは、コンパイル時のチェックを返すため、xUnit.net内からカスタムArbitrariesを使用するための私の好きな方法です。

+2

型付きのxUnit.netプロパティがわかりませんでした。 –

6

瞬間のジャスト拍車をスケッチ - コンパイルされていません。

var genVideo = from w in Arb.Generate<PositiveInt>() 
       from h in Arb.Generate<PositiveInt>() 
       from arrs in Gen.ListOf(Gen.Array2DOf(h, w, Arb.Generate<int>)) 
       select new Video(w, h, arrs); 
+0

これは私に良いスタートを与えましたが、コンパイルする前にちょっと振っておかなければなりませんでした:) –