标签: fscheck

如何保证 FsCheck 的重现性

我们希望在持续集成中使用 FsCheck 作为单元测试的一部分。因此,确定性和可重复的行为对我们来说非常重要。

FsCheck 是一个随机测试框架,可以生成有时可能会中断的测试用例。关键是,我们不仅使用必须为每个输入保留的属性,例如 say List.rev >> List.rev === id。相反,我们做一些数字,一些测试用例可能会因为条件不好而导致测试中断。

问题是:我们如何保证,一旦测试成功,它就永远成功?

到目前为止,我看到以下选项:

  • 对种子进行硬编码,例如 0。这将是最简单的解决方案。
  • 制作非常具体的自定义生成器,避免坏例子。当然可能,但结果可能会非常困难,尤其是在要生成许多对象的情况下。
  • 接受它,在某些情况下,由于病理情况,构建可能是红色的,只需重新运行即可。

在这种设置中使用 FsCheck 的惯用方法是什么?

f# nunit unit-testing fscheck

5
推荐指数
1
解决办法
323
查看次数

在实现基于属性的测试时,何时应该在前置条件表达式上使用输入生成器?

在实现基于属性的测试时,何时应该在前置条件表达式上使用输入生成器?

选择特定选项时是否存在性能因素?

在内部,一种方法是否不可避免地使用另一种方法?

我认为与输入生成器相比,前置条件表达式需要更长的时间才能执行.有没有人测试过这个?

为什么我们需要两者?

f# fscheck property-based-testing

4
推荐指数
1
解决办法
171
查看次数

如何使用FsCheck的固定项目列表创建生成器

我最初尝试创建一个固定前5个元素的生成器(并且在使用Prop.forAll前五个元素的任何测试中总是会运行),但是这样做失败了.

现在我试图通过为一个范围内的随机数据生成一个生成器,并为非随机数据生成一个生成器(即固定序列)来简化此操作.它类似于Gen.constant,除了代替一个值,它是一系列值.

我有这个(简化的可重现的例子,适用于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
Run Code Online (Sandbox Code Playgroud)

输出是(不知道null它来自哪里):

0:
<null>
9223372036854775807L
1:
<null>
-9223372036854775807L
2:
<null>
-9223372036854775807L
3:
<null>
1L
4:
<null>
-9223372036854775807L
Ok, passed 5 tests.
Run Code Online (Sandbox Code Playgroud)

我希望输出包含序列中的所有五个测试,最好是但不一定按顺序排列.我知道我可以使用测试数据提供程序使用NUnit(或任何单元测试系统),但我想知道我是否可以使用FsCheck(或者我是否应该这样做,也许这是一个坏主意).

我认为使用FsCheck是有用的,对于有多个函数参数的情况,我希望它能够详尽地测试我提供的极端情况参数的所有组合.使用FsCheck比使用testdata提供程序更容易.

random f# fscheck

4
推荐指数
1
解决办法
251
查看次数

生成字符串时,Expecto FsCheck会出现堆栈溢出异常

我正在努力学习如何正确使用FsCheck,并将其与Expecto集成.如果我使用默认的FsCheck配置,我可以运行属性测试,但是当我尝试使用自己的Generator时,它会导致堆栈溢出异常.

这是我的发电机

type NameGen() =
    static member Name() =
        Arb.generate<string * string>
        |> Gen.where (fun (firstName, lastName) ->
            firstName.Length > 0 && lastName.Length > 0
        )
        |> Gen.map (fun (first, last) -> sprintf "%s %s" first last)
        |> Arb.fromGen
        |> Arb.convert string id
Run Code Online (Sandbox Code Playgroud)

而我正试图像这样使用它:

let config = { FsCheckConfig.defaultConfig with arbitrary = [typeof<NameGen>] }

let propertyTests input =
    let output = toInitials input
    output.EndsWith(".")

testPropertyWithConfig config "Must end with period" propertyTests
Run Code Online (Sandbox Code Playgroud)

在它进入Gen.where函数之前抛出异常

我究竟做错了什么?谢谢

f# fscheck property-based-testing expecto

4
推荐指数
1
解决办法
163
查看次数

FsCheck:如何生成依赖于其他测试数据的测试数据?

FsCheck具有一些简洁的默认Arbitrary类型来生成测试数据。但是,如果我的一个考试日期取决于另一个考试日期怎么办?

例如,考虑一下string.Substring()结果子字符串的属性永远不能长于输入字符串:

[Fact]
public void SubstringIsNeverLongerThanInputString()
{
    Prop.ForAll(
        Arb.Default.NonEmptyString(),
        Arb.Default.PositiveInt(),
        (input, length) => input.Get.Substring(0, length.Get).Length <= input.Get.Length
    ).QuickCheckThrowOnFailure();
}
Run Code Online (Sandbox Code Playgroud)

尽管Substring当然实现是正确的,但此属性会失败,因为最终PositiveInt会生成比生成的结果更长的a,NonEmptyString从而导致异常。

收缩:NonEmptyString“ a” PositiveInt 2,但例外:System.ArgumentOutOfRangeException:索引和长度必须引用字符串中的位置。

我可以if (input.Length < length) return true;用来保护比较,但是那样的话,即使没有检查该属性,我也会进行大量测试。

如何告诉FsCheck仅生成PositiveInt不超过输入字符串的?我想我必须使用Gen<T>该类,但是它的接口让我感到困惑……我尝试了以下操作,但仍然PositiveInt超出了字符串:

var inputs = Arb.Default.NonEmptyString();
// I have no idea what I'm doing here...
var lengths = inputs.Generator.Select(s => s.Get.Length).ToArbitrary();

Prop.ForAll(
    inputs,
    lengths,
    (input, length) => input.Get.Substring(0, length).Length <= input.Get.Length
).QuickCheckThrowOnFailure();
Run Code Online (Sandbox Code Playgroud)

c# fscheck property-based-testing

4
推荐指数
1
解决办法
429
查看次数

如何使用 C# 中的 FsCheck 自定义生成器?

我有以下代码:

var gen = from x in Arb.Generate<int>()
from int y in Gen.Choose(5, 10)
where x > 5
select new tuple { Fst = x, Snd = y };
Run Code Online (Sandbox Code Playgroud)

我可以跑

Prop.ForAll<tuple>(c =>
      Console.WriteLine($"{c.Fst}, {c.Snd}")
).Check(Configuration.Default);
Run Code Online (Sandbox Code Playgroud)

我看到了构造生成器和定义属性的所有方法。

但我只是没有足够快地找到如何一起使用它们。

fscheck

4
推荐指数
1
解决办法
2013
查看次数

在 FsCheck 中生成自定义数据

我有一个FsCheck问题:
我有以下记录类型(我事先说,我被告知我的单案例 DU 可能是一种矫枉过正,但我​​发现它们描述了域,因此是必要的,我会除非必须,否则不要删除它们):

type Name = Name of string
type Quality = Quality of int
type ShelfLife = Days of int
type Style = Plain | Aged | Legendary

type Item = {
    Name: Name
    Quality: Quality
    ShelfLife: ShelfLife
    Style: Style
}
Run Code Online (Sandbox Code Playgroud)

假设我已经定义了函数repeat: Int -> ('a -> 'a) -> 'adecreaseQuality: Item -> Item,我想编写一个FsCheck检查不变量的测试:任何样式为 OTHER THAN Legendary 的项目,在 100 天过去后,质量为 0

我的问题是我不知道以下内容FsCheck
1. 如何定义一个自定义生成器来生成样式不是传奇的项目?相比之下,我如何定义Legendary 类型的项目(以测试两种类型)?

我调查过: …

f# fscheck

4
推荐指数
1
解决办法
351
查看次数

在FsCheck.XUnit中,如何进行详细检查?

如何获得使用时产生的运行[<Property>]使用Check.VerboseAll一代的风格?

f# xunit xunit.net fscheck

3
推荐指数
1
解决办法
255
查看次数

FsCheck与C#中的NUnit集成

TL; DR:我无法在C#中成功将FsCheck与NUnit结合使用:

  • 它在标准输出上告诉我测试失败,但是测试仍然显示为绿色
  • 它告诉我它找不到任何要运行的测试
  • 或者我不明白如何在C#中应用我阅读的文档

我认为一个虚拟但完整的示例会有所帮助...


(更多细节)

第一步:测试保持绿色

我安装了Nuget软件包FsCheck.NUnit(2.10.4),并且天真地尝试过:

[NUnit.Framework.Test]
public void SomeTest()
{
    // Note the subtle bug: I Reverse only once, because I want the test to fail
    Func<int[],bool> revRevIsOrig = xs => xs.Reverse().SequenceEqual( xs );
    Prop.ForAll(revRevIsOrig).QuickCheck();
}
Run Code Online (Sandbox Code Playgroud)

当我像运行任何NUnit测试一样运行它时,它最终显示为绿色,即使我在stdout上看到

Falsifiable, after 3 tests (1 shrink) (StdGen (2129798881,296376481)):
Original:
[|-1; 0|]
Shrunk:
[|1; 0|]
Run Code Online (Sandbox Code Playgroud)

第二步:测试不确定

所以我继续,找到了一些文档,并注意到我应该使用Property而不是Test。所以我将代码更改为

[FsCheck.NUnit.Property] // <-- the line that changed
public void SomeTest()
{
    Func<int[],bool> revRevIsOrig = xs …
Run Code Online (Sandbox Code Playgroud)

c# nunit unit-testing fscheck

3
推荐指数
1
解决办法
667
查看次数

打开FsCheck时“文件可能被F#交互过程锁定”

当我尝试通过#r“ FsCheck”打开FsCheck命令打开FsCheck时,在.fsx文件中,出现此错误。

尝试使用谷歌搜索,但找不到任何答案可以解决我的问题。

#r“ FsCheck”-打开FsCheck ;;

->引用了“ / * / FsCheck.dll”(文件可能被F#Interactive进程锁定了)

f# f#-interactive fscheck visual-studio-code

3
推荐指数
1
解决办法
96
查看次数