可能是一个愚蠢的问题,但我如何为FSCheck生成特定大小的列表?
我可以限制使用:
let fn_of_2_check xs = (xs.Length=2) ==> fn_of_2 xs
Run Code Online (Sandbox Code Playgroud)
但是,很明显,这会丢掉很多列表.
这里只fn_of_2对长度列表进行一些测试2并返回true或false.
考虑F#中的以下代码
let rec ordered xs =
match xs with
| [] | [_] -> true
| x1 :: x2 :: xs' -> x1 <= x2 && ordered (x2 :: xs')
Run Code Online (Sandbox Code Playgroud)
然后
let rec insert x xs =
match xs with
| [] -> [x]
| y :: ys -> if x <= y then x :: y :: ys
else y :: insert x ys
Run Code Online (Sandbox Code Playgroud)
最后
let insertKeepsOrder (x : int) xs = ordered xs ==> ordered (insert x xs) …Run Code Online (Sandbox Code Playgroud) 我正在 C# 中执行 Diamond Kata,并使用 xUnit 和 FsCheck 在 F# 中编写测试,并且在尝试检查在用户输入无效的情况下是否抛出异常时遇到了一些问题(任何不是的字符) t 一个没有任何变音符号的字母)。下面是代码的样子:
正在测试的方法:
public static string Make(char letter)
{
if (!Regex.IsMatch(letter.ToString(), @"[a-zA-Z]"))
{
throw new InvalidOperationException();
}
// code that makes the diamond
}
Run Code Online (Sandbox Code Playgroud)
考试:
public static string Make(char letter)
{
if (!Regex.IsMatch(letter.ToString(), @"[a-zA-Z]"))
{
throw new InvalidOperationException();
}
// code that makes the diamond
}
Run Code Online (Sandbox Code Playgroud)
我的方法的问题是测试表明没有抛出异常,但是当我使用测试套件显示的输入运行应用程序时,会引发异常。
这是测试套件给出的消息(我故意省略了测试名称和堆栈跟踪):
Test Outcome: Failed
Test Duration: 0:00:00,066
Result Message:
FsCheck.Xunit.PropertyFailedException :
Falsifiable, after 1 test (0 shrinks) (StdGen (1154779780,296216747)):
Original:
')'
---- …Run Code Online (Sandbox Code Playgroud) 嗨,我正在尝试运行FsCheck.Xunit测试xunit.runner.console并获得以下异常:
Kata.TennisProperties.Given advantaged player when advantaged player wins score is correct [FAIL]
System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
---- System.Exception : The type Kata.Tennis+Player is not handled automatically by FsCheck. Consider using another type or writing and registering a generator for it.
Stack Trace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo …Run Code Online (Sandbox Code Playgroud) 我用几个自定义生成器定义了一个类型,以使 FsCheck 生成几个类型的自定义实例。但是对于其中一种复杂类型,我想先使用默认的 FsCheck 生成,然后再调整结果。这是一个(简化的)代码:
type CustomGenerators =
static member FirstCustomType() = /* function that returns FirstCustomType */
static member SecondCustomType() =
Arb.generate<SecondCustomType>
|> Gen.map (fun x -> /* adjust some data in the generated instance */)
|> Arb.fromGen
Run Code Online (Sandbox Code Playgroud)
问题是当 SecondCustomType() 静态方法调用 Arb.generate 时,它会立即调用 SecondCustomType() 导致无限递归。我知道 Arb.generate 必须尊重自定义生成器,所以这就是它调用静态 SecondCustomType() 的原因,但我需要调用 SecondCustomType 的默认(非自定义)Arb.generate 实现。我无法从不同类型调用实现,因为我的自定义生成器使用 FirstCustomType 的自定义生成器,因此默认 SecondCustomType 实现必须知道 CustomGenerators 类型中定义的所有自定义生成器。这是一个糟糕的圈子,我还没有找到一个干净的解决方案(只有解决方法)。
如何生成一个值,使其反映为另一个生成值的元素?
例如,请使用以下代码:
type Space =
| Occupied of Piece
| Available of Coordinate
// Setup
let pieceGen = Arb.generate<Piece>
let destinationGen = Arb.generate<Space>
let positionsGen = Arb.generate<Space list>
Run Code Online (Sandbox Code Playgroud)
我希望positionsGen包含pieceGen和spaceGen生成的值. 但是,我对如何做到这一点毫无头绪.
要在我的问题中添加上下文,我的职位列表(也称为检查板)应该包含生成的部分和列表中生成的目标.
这是我的测试:
[<Property(QuietOnSuccess = true, MaxTest=10000)>]
let ``moving checker retains set count`` () =
// Setup
let pieceGen = Arb.generate<Piece>
let destinationGen = Arb.generate<Space>
let positionsGen = Arb.generate<Space list>
let statusGen = Arb.generate<Status>
// Test
Gen.map4 (fun a b c d -> a,b,c,d) pieceGen destinationGen positionsGen statusGen
|> Arb.fromGen
|> …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 FsCheck 进行基于属性的测试,但我似乎无法弄清楚如何让 FsCheck 使用我已注册的基因。下面是为域生成类型的代码:
module Flips.Gens
open Flips.Domain
open FsCheck
type Silly = {
Name : string
}
let SillyGen () =
gen {
let! NonEmptyString name = Arb.generate<NonEmptyString>
return { Name = name}
}
type Domain () =
static member ArbSillyGen () = Arb.fromGen (SillyGen ())
Run Code Online (Sandbox Code Playgroud)
这是示例测试
module Flips.Tests
open Xunit
open FsCheck
open FsCheck.Xunit
open Flips.Gens
do Arb.register<Domain> () |> ignore
module Tests =
[<Property>]
let ``Silly Name is NonEmptyString`` (silly:Silly) =
let isNullOrEmpty = System.String.IsNullOrEmpty silly.Name …Run Code Online (Sandbox Code Playgroud)