2015-09-27 7 views
12

Video analizi için bazı kodlar yazdığımı varsayalım.C# içinde FsCheck: Aynı şekle sahip iki boyut dizisinin bir listesini oluşturur

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); 
     } 
    } 
} 

Bir Arbitrary<Video> yapmak ve kaydetmek nasıl: Burada Video sınıfının basitleştirilmiş bir versiyonudur? Bu keyfi için bir küçültücü nasıl yapabilirim? Bu çalıştı

, eserlerini nasıl uygulanacağı anlayamadık:

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(); 
} 

bu çalıştı, ama burada liste için jeneratör fiş olamazdı: anın

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(); 
} 

cevap

12

Kurt Schelfthout'un yanıtını temel olarak kullanarak bir Arbitrary yazabilirsiniz.

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(); 
    } 
} 

Bu çeşitli şekillerde kullanabilirsiniz: Böyle video sınıfını r. hangisi tercih süreci bu barındırabilir::

Düz vanilya FsCheck

Burada gerekli değildir burada xUnit.net test durumu içinde barındırılan düz vanilya FsCheck, Video Keyfi nasıl kullanacağınız

Özel Arbittations'larla özellikleri tanımlamak için çok yararlı olan

Prop.ForAll. QuickCheckThrowOnFailure'u aradığınızda, Video sınıfının 'all' (varsayılan: 100) değerlerini test edecek.

Untyped xUnit.net mülkiyet

Ayrıca FsCheck.Xunit Tutkal Kütüphane kullanabilirsiniz, ancak özelliğe bir zayıf yazılan değer olarak Keyfi geçmek zorunda:

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

Bu basit ve anlaşılması kolay, ancak bu Arbitrary özelliğinin atanmasında statik tip denetimi yoktur, bu yüzden bu yaklaşıma çok düşkün değilim.

Yazılan xUnit.net mülkiyet

özel Arbitraries ile FsCheck.Xunit kullanmak için daha iyi bir yoludur combine it with Prop.ForAll için: Bu yöntemin dönüş türü artık void ancak Property olduğunu

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

Bildirim o ; [Property] özniteliği bu türü anlar ve sınamaya göre yürütür.

Bu üçüncü seçenek, derleme zamanı denetimini geri getirdiği için xUnit.net içinden özel Arbittations kullanmanın tercih edilen yoludur.

+2

Yazılan xUnit.net özelliğini bilmiyordum, bu harika bir seçenek! –

6

Sadece bir mahmuz eskiz - derlenmemiş :)

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

Bu bana iyi bir başlangıç ​​yaptı, ancak derhal biraz önce onu karıştırmak zorunda kaldım :) –

İlgili konular