C#中的FsCheck:生成具有相同形状的二维数组的列表

假设我正在为video分析编写一些代码。 以下是Video类的简化版本:

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

如何制作Arbitrary并进行注册? 如何为该任意制作收缩机?

试过这个,无法理解申请是如何运作的:

 public static Arbitrary 

试过这个,但无法在这里插入生成器列表:

 public static Arbitrary 

使用Kurt Schelfthout的答案作为基础,您可以像这样为video类编写一个任意对象:

 public static class VideoArbitrary { public static Arbitrary 

您可以通过各种方式使用它。

普通香草FsCheck

以下是如何将video任意与简单的香草FsCheck一起使用,此处托管在xUnit.net测试用例中,这不是必需的:您可以在您喜欢的任何过程中托管它:

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

Prop.ForAll对于使用自定义Arbitraries定义属性非常有用。 当您调用QuickCheckThrowOnFailure ,它将运行Video类的’all’(通过defailt:100)值的测试。

无法输入xUnit.net属性

您也可以使用FsCheck.Xunit Glue Library,但必须将Arbitrary作为弱类型值传递给属性:

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

这很简单易懂,但在分配Arbitrary属性时没有涉及静态类型检查,所以我不太喜欢这种方法。

键入xUnit.net属性

将FsCheck.Xunit与自定义Arbitraries一起使用的更好方法是将它与Prop.ForAll结合使用 :

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

请注意,此方法的返回类型不再是void ,而是Property ; [Property]属性理解此类型并相应地执行测试。

第三个选项是我在xUnit.net中使用自定义Arbitraries的首选方法,因为它带回了编译时检查。

只是一刻的草图 – 没有编译:)

 var genVideo = from w in Arb.Generate() from h in Arb.Generate() from arrs in Gen.ListOf(Gen.Array2DOf(h, w, Arb.Generate)) select new Video(w, h, arrs);