Pav*_*gin 12 c# unit-testing fscheck generative-testing
假设我正在为视频分析编写一些代码.以下是Video类的简化版本:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我如何制作Arbitrary<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();
}
Run Code Online (Sandbox Code Playgroud)
试过这个,但无法在这里插入生成器列表:
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();
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*ann 13
使用Kurt Schelfthout的答案作为基础,你可以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();
}
}
Run Code Online (Sandbox Code Playgroud)
您可以通过各种方式使用它.
以下是如何将视频任意与简单的香草FsCheck一起使用,这里托管在xUnit.net测试用例中,这不是必需的:您可以在您喜欢的任何过程中托管它:
[Fact]
public void VideoProperty()
{
var property = Prop.ForAll(
VideoArbitrary.Videos(),
video =>
{
// Test goes here...
Assert.NotNull(video);
});
property.QuickCheckThrowOnFailure();
}
Run Code Online (Sandbox Code Playgroud)
Prop.ForAll对于使用自定义Arbitraries定义属性非常有用.当你打电话时QuickCheckThrowOnFailure,它将运行该类的'all'(通过defailt:100)值的测试Video.
您也可以使用FsCheck.Xunit Glue Library,但您必须将Arbitrary作为弱类型值传递给属性:
[Property(Arbitrary = new[] { typeof(VideoArbitrary) })]
public void XunitPropertyWithWeaklyTypedArbitrary(Video video)
{
// Test goes here...
Assert.NotNull(video);
}
Run Code Online (Sandbox Code Playgroud)
这很简单易懂,但在分配该Arbitrary属性时没有涉及静态类型检查,所以我不太喜欢这种方法.
将FsCheck.Xunit与自定义Arbitraries一起使用的更好方法是将它与Prop.ForAll结合使用:
[Property]
public Property XUnitPropertyWithStronglyTypedArbitrary()
{
return Prop.ForAll(
VideoArbitrary.Videos(),
video =>
{
// Test goes here...
Assert.NotNull(video);
});
}
Run Code Online (Sandbox Code Playgroud)
请注意,此方法的返回类型不再是void,但是Property; 的[Property]属性理解这种类型,并相应地执行该测试.
第三个选项是我在xUnit.net中使用自定义Arbitraries的首选方法,因为它带回了编译时检查.
只是一刻的草图 - 没有编译:)
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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1372 次 |
| 最近记录: |