如何使用 FsCheck 实现多参数生成?

2024-02-01

如何使用 FsCheck 实现多参数生成?

我实现了以下内容来支持多个参数生成:

// Setup
let pieces =    Arb.generate<Piece> |> Gen.filter (isKing >> not)
                                    |> Arb.fromGen  

let positionsList = Arb.generate<Space list> |> Arb.fromGen

然后,我使用这些参数来测试负责为给定检查器生成移动选项的函数的行为:

// Test
Prop.forAll pieces <| fun piece ->
    Prop.forAll positionsList <| fun positionsItem ->

        positionsItem |> optionsFor piece 
                      |> List.length <= 2

管理多个生成的参数类型时,嵌套 Prop.forAll 表达式是正确的技术吗?

是否有其他方法可以为被测函数生成多个参数?

这是整个函数:

open FsCheck
open FsCheck.Xunit

[<Property(QuietOnSuccess = true)>]
let ``options for soldier can never exceed 2`` () =

    // Setup
    let pieces =    Arb.generate<Piece> |> Gen.filter (isKing >> not)
                                        |> Arb.fromGen  

    let positionsList = Arb.generate<Space list> |> Arb.fromGen

    // Test
    Prop.forAll pieces <| fun piece ->
        Prop.forAll positionsList <| fun positionsItem ->

            positionsItem |> optionsFor piece 
                          |> List.length <= 2

UPDATE

这是我的问题的解决方案,源自马克的回答:

[<Property(QuietOnSuccess = true, MaxTest=100)>]
let ``options for soldier can never exceed 2`` () =

    // Setup
    let pieceGen =     Arb.generate<Piece> |> Gen.filter (isKing >> not)
    let positionsGen = Arb.generate<Space list>

    // Test
    (pieceGen , positionsGen) ||> Gen.map2 (fun x y -> x,y)
                               |> Arb.fromGen
                               |> Prop.forAll <| fun (piece , positions) -> 
                                                   positions |> optionsFor piece 
                                                             |> List.length <= 2

作为一般观察,Arbitrary值很难组合,而Gen价值观很容易。出于这个原因,我倾向于根据以下方面来定义我的 FsCheck 构建块:Gen<'a>代替Arbitrary<'a>.

With Gen值,您可以使用组合多个参数Gen.map2, Gen.map3等,或者您可以使用gen计算表达式。

Gen 积木

在OP示例中,不是定义pieces and positionsList as Arbitrary,将它们定义为Gen values:

let genPieces = Arb.generate<Piece> |> Gen.filter (isKing >> not)

let genPositionsList = Arb.generate<Space list>

这些是类型的“构建块”Gen<Piece> and Gen<Space list>, 分别。

请注意我给它们起了名字genPieces而不是简单地pieces, 等等。这可以防止以后发生名称冲突(见下文)。 (另外,我不确定复数的使用s in pieces, 因为genPieces只生成一个Piece值,但由于我不知道您的整个域,所以我决定保持原样。)

如果您只需要其中之一,可以将其转换为Arbitrary using Arb.fromGen.

如果需要组合它们,可以使用映射函数或计算表达式之一,如下所示。这会给你一个Gen元组,然后你可以使用Arb.fromGen将其转换为Arbitrary.

使用map2编写

如果您需要作曲pieces and positionsList到参数列表中,您可以使用Gen.map2:

Gen.map2 (fun x y -> x, y) genPieces genPositionList
|> Arb.fromGen
|> Prop.forAll <| fun (pieces, positionList) -> 
    // test goes here...

Gen.map2 (fun x y -> x, y)返回一个二元素元组(apair)的值,您可以将其解构为(pieces, positionList)在匿名函数中。

这个例子也应该可以清楚地说明原因genPieces and genPositionList是更好的名字Gen价值观:他们为使用“裸名”留出空间pieces and positionList用于传递给测试主体的生成值。

使用计算表达式进行编写

对于更复杂的组合,我有时更喜欢的另一种选择是使用gen计算表达式。

上面的例子也可以这样写:

gen {
    let! pieces = genPieces
    let! positionList = genPositionList
    return pieces, positionList }
|> Arb.fromGen
|> Prop.forAll <| fun (pieces, positionList) -> 
    // test goes here...

最初的gen表达式也返回一个对,所以它相当于组合Gen.map2.

您可以使用您认为最可读的选项。

你可以看到更多不平凡的例子Gen我文章中的组合通过基于属性的 TDD 的罗马数字 http://blog.ploeh.dk/2016/06/28/roman-numerals-via-property-based-tdd.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 FsCheck 实现多参数生成? 的相关文章

  • 在 F# 中处理 Deedle 时间序列中的缺失值 (1)

    这是一个小例子 我想处理系列上自定义函数的缺失值 假设我已经获得了一系列 series4 val it Series
  • Silverlight 如何确定程序集是“Silverlight”?

    我正在尝试从 F 编译代码以在 Silverlight 中使用 我编译 noframework cliroot C program Files Microsoft Silverlight 2 0 31005 0 standalone 这会生
  • F#:将字符串选项转换为字符串的最短方法

    目标是转换一个string option这是通过一些很好的类型计算得出的一个简单的string然后可以传递到 UI printf URL 其他只想要一个字符串并且对选项类型一无所知的东西 None应该变成空字符串 显而易见的方法是做一个ma
  • 使用 F# 的爱因斯坦之谜解决方案 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我在找爱因斯坦之谜 http en
  • 没有带有常量“模板参数”的 F# 泛型?

    我突然想到 F 泛型似乎不接受常量值作为 模板参数 假设有人想创建一种类型RangedInt这样 它的行为类似于 int 但保证只包含整数值的子范围 一种可能的方法是建立受歧视的工会 类似于 type RangedInt Valid of
  • F# 设置带有参数的 SQLCommand 的最佳方法

    我的 F 程序需要与 SQL Server 通信 在一部分中我有这样的事情 let workFlowDetailRuncommand new SqlCommand query econnection workFlowDetailRuncom
  • 使用 F# 进行循环与递归

    这里的示例代码解决了一个项目欧拉问题 从数字 1 开始 按顺时针方向向右移动 方向 5 x 5 螺旋形成如下 21 22 23 24 25 20 7 8 9 10 19 6 1 2 11 18 5 4 3 12 17 16 15 14 13
  • 在 F# 中组合谓词

    F 中是否有逻辑组合谓词的标准方法 例如 假设我有isCar x and isBlue x然后我想要一些能给我的东西 let isBlueCar x isCar x isBlue x 但是使用某种组合而不是调用 可能像 let isBlue
  • 如何在 x 轴上显示每个元素的标签?

    我有包含文件名和编号的元组序列 我想绘制柱形图 其中 X 轴上有文件名 我的问题是现在 X 轴下仅显示 3 个标签 文件名 这可能是因为屏幕无法容纳更多内容 还是X轴间隔错误 如何让图表显示所有文件名 也许有办法将这些标签逆时针旋转 90
  • 绘图 Deedle 框架

    我有以下代码 let mychart frame GetAllSeries gt Seq iter fun key value gt Chart Line value Name key gt Chart Combine where fram
  • Async.TryCancelled 不适用于 Async.RunSynchronously

    我尝试创建一个根据用户交互更新 UI 的代理 如果用户单击按钮 则应刷新 GUI 模型的准备需要很长时间 因此希望如果用户单击其他按钮 则取消准备并开始新的准备 到目前为止我所拥有的 open System Threading type p
  • FParsec:如何组合解析器以便它们以任意顺序匹配

    任务是找到特定的键值对并解析它们 这些对可以按任何顺序出现 我的部分工作尝试 open FParsec type Parser lt a gt Parser lt a unit gt type Status Running Done typ
  • F# 参数传递

    我一直认为 F 有两种不同的方式来传递参数 柯里化风格和元组风格 这实际上是正确的吗 是不是很简单一种风格 柯里化风格和参数可以是简单值或元组 e g someFunc a b 这不是一个函数吗one咖喱风格的参数恰好是一个元组 因此允许我
  • 在 F# 中“合并”受歧视的联合?

    继从这个问题 https stackoverflow com questions 53506325 result vs raise in f async 我在组合不同类型时遇到问题Result类型在一起 以下是一个人为的示例 不是真实的代码
  • `ImmutableSortedSet` 和 fsharp `Set` 有什么区别?

    BCL引入了一组Immutable Collections http blogs msdn com b bclteam archive 2012 12 18 preview of immutable collections released
  • 什么是错误“类型实例化涉及 byref 类型。” F# 中的解决方法是什么

    我有一些代码包装 TA Lib 很多包装器非常相似 let sma timePeriod int data float let mutable outStartIndex 0 let mutable outNbElement 0 let m
  • 当两个模式共享“when”子句时,模式匹配不完整

    A 共同的惊喜 https stackoverflow com q 18691622 2314532对于 F 初学者来说 以下事实是不完全匹配 let x y 5 10 match something with when x lt y gt
  • 使用 SqlBulkCopy 和 F# 在 SQL 中导出矩阵

    我想将大量数据从 F 传输到 SQL 表 基本上我的 F 代码创建了一个三列矩阵 UserID ProductID and price 和N行 我想将其 复制 粘贴 到数据库中 我尝试了多种选择 但最终 从 F 传输数据非常慢 10000
  • “不等于”的 F# 语法是什么?

    在 C 代码中 它会是这样的 if c 0 some code 那么在 F 中呢 From MSDN 有关 F 算术运算符的页面 http msdn microsoft com en us library dd469493 aspx 看起来
  • 将 F# 类型保存到数据库

    A lot http gorodinski com blog 2013 02 17 domain driven design with fsharp and eventstore f 文章数推荐 http fsharpforfunandpr

随机推荐