在寻找答案时,我发现了几个与我的情况不太匹配的问题 - 所以我会问一个新问题.
我正在为数据结构编写一些FsCheck测试,我想在我构建的数据结构的每个副本上检查20个不同的属性.到目前为止我所做的是为每个属性编写一个谓词,然后我创建了一个谓词列表,我将依次调用它们List.forall
,如下所示:
module PropertyChecks =
let ``Tail length plus tree length should equal vector length`` vec =
treeLength vec.root + Array.length vec.tail = vec.len
let ``The tail may only be empty iff the vector is empty`` vec =
(vec.len = 0) = (Array.length vec.tail = 0)
let ``The tail's length may not exceed tailMax`` vec =
Array.length vec.tail < tailMax
let ``If vec.len <= tailMax, all items are in tail and root is empty`` vec =
(vec.len > tailMax) || (Array.length vec.root = 0)
// And so on for about 15 more predicates
let allProperties =
[
``Tail length plus tree length should equal vector length``
``The tail may only be empty iff the vector is empty``
``The tail's length may not exceed tailMax``
``If vec.len <= tailMax, all items are in tail and root is empty``
]
let checkProperties vec =
allProperties |> List.forall (fun pred -> pred vec)
// Rest of my code omitted since it's not relevant to the question
Run Code Online (Sandbox Code Playgroud)
我面临的问题是,我希望当一个属性因为我没有正确构造数据结构而失败时,两个或三个其他属性将同时失败.我想获得所有失败属性的列表,这意味着checkProperties
我想提取失败谓词的名称.我已经看到了多个答案:"你无法MethodInfo
从作为参数获得的任意F#函数中获取,因为你永远不知道你是否拥有函数本身,或者是lambda,还是匿名函数".但在这里,我不仅知道我有真正的功能,我知道他们的名字是什么.我可以轻松地将其名称复制并粘贴到字符串中,并allProperties
列出(字符串,函数)元组.但是我已经对复制和粘贴一次(将谓词放入该列表)感到不满意,而我宁愿不做两次.
制作(函数名称,函数)元组列表的更好的解决方案是什么?我可以移动allProperties
和checkProperties
移出PropertyChecks
模块,使它只包含谓词,然后使用反射来走动该模块吗?
我对整个.Net反射系统都很陌生,所以我很可能会遗漏一些明显的东西.如果我错过了,请随时指出明显的; 我不会感到被侮辱.
运行FsCheck测试的最佳选择是将FsCheck与一些单元测试运行器一起使用.测试运行器负责查找所有属性,运行它们并在出现问题时打印漂亮的错误日志.
.NET中与FsCheck一起使用的两个最常见的测试运行器是xUnit和NUnit,FsCheck文档描述了如何使用它们:
在这两种情况下,您[<Property>]
都使用属性标记属性,测试运行器将使用它来查找它们并使用FsCheck为您运行它们.所以你需要这样的东西:
[<Property>]
let ``Tail length plus tree length should equal vector length`` vec =
treeLength vec.root + Array.length vec.tail = vec.len
[<Property>]
let ``The tail may only be empty iff the vector is empty`` vec =
(vec.len = 0) = (Array.length vec.tail = 0)
[<Property>]
let ``The tail's length may not exceed tailMax`` vec =
Array.length vec.tail < tailMax
[<Property>]
let ``If vec.len <= tailMax, all items are in tail and root is empty`` vec =
(vec.len > tailMax) || (Array.length vec.root = 0)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
75 次 |
最近记录: |