我有一个类型,Average其中一个字段count是正面的int64,一个double字段叫做sum.
我做了一个任意生成有效的实例
let AverageGen = Gen.map2 (fun s c -> Average(float(s),int64(int(c))) (Arb.Default.NormalFloat().Generator) (Arb.Default.PositiveInt().Generator) |> Arb.fromGen
Run Code Online (Sandbox Code Playgroud)
如何Property在xUnit 中的样式测试中生成具有Average类型的参数?
[<Property>]
static member average_test(av:Average) = ...
Run Code Online (Sandbox Code Playgroud) 有没有办法在FsCheck中生成一个字符串,只从每个字符串列表中选择一个项目然后连接结果?
我只是完全陷入困境,似乎无法弄明白.我查看了文档和github repo中的类似内容.而且我已经从FSharpForFunAndProfit完成了对FsCheck的大部分阅读.
这就像我想的那样:
let rand = System.Random()
let randInt max = rand.Next(0, max)
let selectLetter (string: string) =
let whichLettersIndex = String.length string |> randInt
string.Substring(whichLettersIndex, 1)
let generateOddlySpelledWord listOfStrings =
List.map selectLetter listOfStrings
|> String.concat ""
let usingGenerateOddlySpelledWord =
generateOddlySpelledWord ["zZ"; "oO0Ò"; "eEê"]
Run Code Online (Sandbox Code Playgroud)
这应该产生类似"Z0ê"或"zÒE"的东西.
我正在玩FsCheck所以我有这个实现:
let add a b =
if a > 100
then failwith "nasty bug"
else a + b
Run Code Online (Sandbox Code Playgroud)
......以及基于FsCheck的测试:
fun (a:int) -> (add a 0) = a
|> Check.QuickThrowOnFailure
Run Code Online (Sandbox Code Playgroud)
而测试永远不会失败.我的猜测是随机生成器产生的100个值绝不会大于100.
价值不应该更"随机"吗?
在F#中,我有几个字段的记录:
type myRecord = { a:float; b:float; c:float }
Run Code Online (Sandbox Code Playgroud)
我正在使用FsCheck来测试一些使用此记录的属性.对于(一个人为的)例子,
let verify_this_property (r:myRecord) = myFunction(r) = (r.a * r.b) / r.c
Run Code Online (Sandbox Code Playgroud)
由于myFunction的内部实现限制,我想让FsCheck创建测试用例,其中每个字段a,b,c都限制为非负浮点数.
我怀疑这需要为myRecord创建一个生成器,但我无法找到任何如何执行此操作的示例.
谁能提供指导?
我有一个函数可以生成一定范围内的双精度数:
let gen_doublein =
fun mx mn -> Arb.generate<float> |> Gen.suchThat ( (>) mx ) |> Gen.suchThat ( (<) mn )
Run Code Online (Sandbox Code Playgroud)
然后是一个函数来生成其中 2 个数组:
let gen_params:Gen<double array> =
gen { let! x = gen_doublein 0.0 20000.0
let! y = gen_doublein 0.0 2000.0
return [| x;y|] }
Run Code Online (Sandbox Code Playgroud)
我放:
static member arb_params = Arb.fromGen gen_params
Run Code Online (Sandbox Code Playgroud)
在 Generator 类中并注册它。一切看起来都不错。为了测试这是否一切正常,我有:
let f2 (xs:double array) :double= exp (-2.0*xs.[0]) + xs.[1]*exp (-2.0*xs.[0])
let fcheck fn xs = fn xs > 0.0
Run Code Online (Sandbox Code Playgroud)
然后使用数组生成器“arrayOfLength”:
Check.Quick (Prop.forAll (arrayOfLength 2) …Run Code Online (Sandbox Code Playgroud) 我们希望在持续集成中使用 FsCheck 作为单元测试的一部分。因此,确定性和可重复的行为对我们来说非常重要。
FsCheck 是一个随机测试框架,可以生成有时可能会中断的测试用例。关键是,我们不仅使用必须为每个输入保留的属性,例如 say List.rev >> List.rev === id。相反,我们做一些数字,一些测试用例可能会因为条件不好而导致测试中断。
问题是:我们如何保证,一旦测试成功,它就永远成功?
到目前为止,我看到以下选项:
在这种设置中使用 FsCheck 的惯用方法是什么?
我正在尝试使用 FsCheck 初始化我的模型实体。这些模型位于 C# 中,通常通过实体框架的私有设置器进行初始化。例如(人为的):
public class Model
{
public string One { get; private set; }
public int Two { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个 FsCheck 生成器,它自动使用每个属性的注册生成器来生成模型。像这样的东西:
let modelGenerator =
gen {
let incident = new Model()
typeof<Model>.GetProperties()
|> Array.filter (fun p -> p.CanWrite)
|> Array.iter (fun p ->
let! newVal = Arb.generateType p.PropertyType // I wish I could do this
p.SetValue(incident, newVal))
return incident
}
Run Code Online (Sandbox Code Playgroud)
这有两个问题:
let!之外使用gen。Arb.generateType不存在,而且我找不到一种方法来做到这一点是否可以创建一个生成器来自动在我的模型上设置私有字段?
我正在使用FsCheck在F#中进行一些属性测试.因此,无论输入参数如何,我都希望保证某些条件始终存在.
考虑我为float值定义一个简单的标识函数.
let floatId (x : float) = x
Run Code Online (Sandbox Code Playgroud)
然后我定义了这个函数的测试,我知道应该总是这样:
let ``floatId returns input float`` x = floatId x = x
Run Code Online (Sandbox Code Playgroud)
这是一个简单的测试,我只是检查调用我的float identity函数返回与输入float相同.
然后我将此函数插入FsCheck:
Check.Quick ``floatId returns input float``
Run Code Online (Sandbox Code Playgroud)
不幸的是,这个属性测试失败!
Run Code Online (Sandbox Code Playgroud)Falsifiable, after 21 tests (0 shrinks) (StdGen (1872424299,296201373)): Original: nan
当然,回顾过去,很明显这将会发生,我们知道nan <> nan.
由于F#中的结构比较,这可能会困扰(稍微)涉及集合的更复杂的测试案例.
如果我为浮点列表设计一个类似的函数:
let listFloatId (lst : float list) = lst
let ``listFloatId returns input float list`` lst = listFloatId lst = lst
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)Falsifiable, after 6 tests (3 shrinks) (StdGen (1874889363,296201373)): Original: [nan; 2.0; …
我认为现在是时候尝试FsCheck,但事实证明它比我想象的更难.有很多文档Arb,生成器等等,但似乎没有任何关于如何应用这些知识的指导.或者我只是没有得到它.
可能让人更难理解的是,测试,属性,生成器,仲裁,缩小以及在我的情况下,随机性(一些测试自动生成随机数据,其他测试没有)之间的关系对我来说并不清楚.我没有Haskell背景,所以也没有多大帮助.
现在问题是:如何生成随机整数?
我的测试场景可以用乘法的属性来解释,比如分配:
static member ``Multiplication is distributive`` (x: int64) y z =
let res1 = x * (y + z)
let res2 = x * y + x * z
res1 = res2
// run it:
[<Test>]
static member FsCheckAsUnitTest() =
Check.One({ Config.VerboseThrowOnFailure with MaxTest = 1000 }, ``Multiplication is distributive``)
Run Code Online (Sandbox Code Playgroud)
当我使用Check.Verbose或NUnit集成运行时,我得到的测试序列如下:
0:
(-1L, -1L, -1L)
1:
(-1L, -1L, 0L)
2:
(-1L, -1L, -1L)
3:
(-1L, -1L, -1L)
4:
(-1L, 0L, -1L)
5:
(1L, …Run Code Online (Sandbox Code Playgroud)