- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在 VisualStudio 中使用 FsCheck 和 NUnit 进行测试。
当前的问题是:我设法生成随机图(用于测试某些图功能),但是当测试失败时,FsCheck 会吐出整个图,并且它不使用 ToString,因此它实际上会转储原始记录列表,而您不能看到里面有什么。
此外,我不仅需要用于检查的输入图,还需要运行属性时创建的一些其他数据。
那么我如何更改 FsCheck 的输出行为以便
当测试失败时?
编辑:这是我当前的测试设置。
module GraphProperties
open NUnit.Framework
open FsCheck
open FsCheck.NUnit
let generateRandomGraph =
gen {
let graph: Graph<int,int> = Graph<_,_>.Empty()
// fill in random nodes and transitions...
return graph
}
type MyGenerators =
static member Graph() =
{new Arbitrary<Graph<int,int>>() with
override this.Generator = generateRandomGraph
override this.Shrinker _ = Seq.empty }
[<TestFixture>]
type NUnitTest() =
[<Property(Arbitrary=[|typeof<MyGenerators>|], QuietOnSuccess = true)>]
member __.cloningDoesNotChangeTheGraph (originalGraph: Graph<int,int>) =
let newGraph = clone originalGraph
newGraph = originalGraph
最佳答案
FsCheck 使用sprintf "%A"
要将测试参数转换为测试输出中的字符串,因此您需要做的是控制 %A
的类型格式化方式。格式化程序。根据How do I customize output of a custom type using printf? ,方法是使用 StructuredFormatDisplay
attribute 。该属性的值应该是格式为 PreText {PropertyName} PostText
的字符串。 ,其中PropertyName
应该是您类型的属性(而不是函数!)。例如,假设您有一个树结构,叶子中包含一些复杂的信息,但对于您的测试,您只需要了解叶子的数量,而不是叶子中的内容。因此,您可以从这样的数据类型开始:
// Example 1
type ComplicatedRecord = { ... }
type Tree =
| Leaf of ComplicatedRecord
| Node of Tree list
with
member x.LeafCount =
match x with
| Leaf _ -> 1
| Node leaves -> leaves |> List.sumBy (fun x -> x.LeafCount)
override x.ToString() =
// For test output, we don't care about leaf data, just count
match x with
| Leaf -> "Tree with a total of 1 leaf"
| Node -> sprintf "Tree with a total of %d leaves" x.LeafCount
现在,到目前为止这还不是您想要的。此类型没有有自定义 %A
format 声明,因此 FsCheck(以及使用 sprintf "%A"
对其进行格式化的任何其他内容)最终将输出树的整个复杂结构及其所有与测试无关的叶数据。要使 FsCheck 输出您想要看到的内容,您需要设置一个属性,而不是一个输出您想要看到的内容的函数( ToString
无法用于此目的) 。例如:
// Example 2
type ComplicatedRecord = { ... }
[<StructuredFormatDisplay("{LeafCountAsString}")>]
type Tree =
| Leaf of ComplicatedRecord
| Node of Tree list
with
member x.LeafCount =
match x with
| Leaf _ -> 1
| Node leaves -> leaves |> List.sumBy (fun x -> x.LeafCount)
member x.LeafCountAsString = x.ToString()
override x.ToString() =
// For test output, we don't care about leaf data, just count
match x with
| Leaf -> "Tree with a total of 1 leaf"
| Node -> sprintf "Tree with a total of %d leaves" x.LeafCount
注意:我还没有在 F# 中对此进行测试,只是将其输入到 Stack Overflow 注释框中 - 所以我可能搞乱了 ToString()
部分。 (我不记得了,也无法通过快速谷歌找到覆盖是否应该在 with
关键字之后或之前)。但我知道StructuredFormatDisplay
属性就是您想要的,因为我自己使用它来从 FsCheck 中获取自定义输出。
顺便说一句,您也可以设置 StructuredFormatDisplay
在我的示例中,复杂记录类型的属性也是如此。例如,如果您有一个测试,您关心树结构而不是叶子的内容,那么您可以这样写:
// Example 3
[<StructuredFormatDisplay("LeafRecord")>] // Note no {} and no property
type ComplicatedRecord = { ... }
type Tree =
| Leaf of ComplicatedRecord
| Node of Tree list
with
member x.LeafCount =
match x with
| Leaf _ -> 1
| Node leaves -> leaves |> List.sumBy (fun x -> x.LeafCount)
override x.ToString() =
// For test output, we don't care about leaf data, just count
match x with
| Leaf -> "Tree with a total of 1 leaf"
| Node -> sprintf "Tree with a total of %d leaves" x.LeafCount
现在你所有的ComplicatedRecord
实例,无论其内容如何,都将显示为文本 LeafRecord
在你的输出中,你将能够更好地关注树结构 - 并且不需要设置 StructuredFormatDisplay
Tree
上的属性类型。
这不是一个完全理想的解决方案,因为您可能需要调整 StructuredFormatDisplay
根据您正在运行的各种测试的需要,不时地更改属性。 (对于某些测试,您可能希望关注叶数据的一部分,对于其他测试,您可能希望完全忽略叶数据,等等)。您可能希望在投入生产之前删除该属性。但在 FsCheck 获得“给我一个函数来格式化失败的测试数据”配置参数之前,这是按照您需要的方式格式化测试数据的最佳方法。
关于f# - 自定义 FsCheck 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45444084/
我有以下代码: var gen = from x in Arb.Generate() from int y in Gen.Choose(5, 10) where x > 5 select new tu
总结 是否有任何事件可以在每个属性案例之前运行,以便我可以为属性的每次运行运行设置和拆卸? 完整版 我希望能够使用属性测试配对行为,例如“我总是可以获取书面记录”或“readAllLines 的输出等
我的代码在使用 FsCheck 时会自动测试从 -99 到 99 的值。 Check.Quick test 我的测试函数采用整数值。 我想使用 1 到 4999 之间的值进行测试。 最佳答案 您可以使
FsCheck 有一些简洁的默认值 Arbitrary类型来生成测试数据。但是,如果我的一个考试日期取决于另一个考试日期怎么办? 例如,考虑 string.Substring() 的属性结果子字符串永
我似乎经常遇到这样的情况,我想生成一些复杂的结构,但生成的成员类型的特殊变体却不同。 例如,考虑这棵树 type Tree = | LeafNode of 'LeafData | In
我有一个 FsCheck题: 我有以下记录类型(我事先说过,有人告诉我我的单例 DU 可能有点矫枉过正,但我发现它们描述了域,因此是必要的,除非必须,否则我不会删除它们): type Name =
我有一个函数可以在一个范围内生成 double : let gen_doublein = fun mx mn -> Arb.generate |> Gen.suchThat ( (>) mx
我最初尝试创建一个固定前 5 个元素的生成器(并且在使用 Prop.forAll 的任何测试中,前五个总是会运行),但失败了。 现在我试图通过一个范围内的随机数据生成器和一个非随机数据的生成器(即固定
有没有办法通过从每个字符串列表中只选择一个项目然后连接结果来在 FsCheck 中生成一个字符串? 我只是完全卡住了,似乎无法弄清楚。我看过 docs并在 github repo 类似的东西。我从 F
我正在尝试对此功能进行测试 let extract_one_rule (rule:Rule.t) = let rec expand = function |PAlt (a,b)
我想使用 FsCheck(与 XUnit)创建类型的记录:type QueryRequest = {Symbol: string; StartDate: DateTime; EndDate: Date
我设法得到xUnit处理我的小样本组装。现在我想看看我能不能摸索FsCheck也。我的问题是在为我的函数定义测试属性时我很困惑。 也许我只是没有一个好的函数样本集,但是例如,这些函数的好的测试属性是什
是否可以使用 fscheck 生成数据,特别是列表,以便在 fscheck 之外使用?我无法在 fscheck 测试中调试比较结果看起来相等的情况,但 fscheck 说它们不相等。 我有这个对象列表
我正在 VisualStudio 中使用 FsCheck 和 NUnit 进行测试。 当前的问题是:我设法生成随机图(用于测试某些图功能),但是当测试失败时,FsCheck 会吐出整个图,并且它不使用
我想测试一个属性,我使用 2 个概率 p1 和 p2 必须满足 0 ) = (p1 0.0 && p1 0.0 && p2 0) ==> (lazy ( let bf1
我使用 FsCheck 进行基于属性的测试,因此我为自定义类型定义了一组生成器。有些类型由其他类型组成,并且所有类型都有生成器。为字母数字类型定义了一个生成器后,我想为 RelativeUrl 类型定
我正在编写一个 FSCheck 生成器来创建具有以下属性的字符串: 它们是非空的 修剪它们不会影响长度 它们不包含空格。 这是我的生成器代码: namespace Example open FsChe
如何使用 FsCheck 实现多参数生成? 我实现了以下内容以支持多参数生成: // Setup let pieces = Arb.generate |> Gen.filter (isKing
我有这样的递归类型: type QueryInfo = { Title : string Check : Client -> bool Positive :
我正在尝试采用 fscheck,但由于没有太多 C# 文档,所以遇到了很多困难。您能解释一下,为什么以下使用 When 组合器的示例会失败(显然,我不明白如何正确使用它)? [Test] p
我是一名优秀的程序员,十分优秀!