f# - 使用 FsCheck 生成记录

标签 f# fscheck

我想使用 FsCheck(与 XUnit)创建类型的记录:type QueryRequest = {Symbol: string; StartDate: DateTime; EndDate: DateTime}其中 Symbol仅限于 3 个选项 - ORCL , IBM , AAPL , 和 StartDateEndDate仅限于2000年1月1日2019年1月1日之间的范围。

但是,我不清楚如何进行。我应该使用 Arb.generate<T> 吗?或 Arb.Default还是生成和缩减测试用例所依据的其他一些实用程序?


更新 1

与生成记录相关的后续问题可用 here .

Original:
{ Symbol = ""
  StartDate = 8/9/2057 4:07:10 AM
  EndDate = 10/14/2013 6:15:32 PM }
Shrunk:
{ Symbol = ""
  StartDate = 8/9/2057 12:00:00 AM
  EndDate = 10/14/2013 12:00:00 AM }

更新 2

以下是测试套件代码:

namespace Parser

open Xunit
open FsCheck.Xunit
open DataGenerators

module Tests =
    [<Fact>]
    let ``sanity check`` () =
        let expected = true
        let actual = true
        Assert.Equal(expected, actual)

    [<Property(Arbitrary = [|typeof<StockTwitGenerator>|])>]
    let ``validate queries`` (q: QueryRecord) =
        q.EndDate > q.StartDate

最佳答案

当您具有将值限制为给定类型的所有允许值的一小部分的约束时,构造有效值比过滤更容易和更安全1

鉴于...

open FsCheck
open System

type QueryRequest = {Symbol: string; StartDate: DateTime; EndDate: DateTime}

...我们可以从为 Symbols 创建一个生成器开始:

let symbols = ["ORCL"; "IBM"; "AAPL"]
let symbol = Gen.elements symbols

和日期范围

let minDate = DateTime(2000, 1, 1)
let maxDate = DateTime(2019, 1, 1)
let dateRange = maxDate - minDate
let date =
    Gen.choose (0, int dateRange.TotalDays)
    |> Gen.map (float >> minDate.AddDays)

请注意,Gen.choose 仅接受 int 范围。我们可以通过生成最大允许日期差异的随机偏移量然后映射回 DateTime

来解决

使用这些,我们可以为 QueryRequest 构建一个生成器...

let query =
    gen {
        let! s = symbol
        let! d1 = date
        let! d2 = date
        let startDate, endDate = if d1 < d2 then d1, d2 else d2, d1 
        return { Symbol = s; StartDate = startDate; EndDate = endDate }
    }

type MyGenerators =
  static member QueryRequest() =
      {new Arbitrary<QueryRequest>() with
          override _.Generator = query }

...注册...

Arb.register<MyGenerators>()

最后测试:

let test { Symbol = s; StartDate = startDate; EndDate = endDate } =
    symbols |> Seq.contains s && startDate >= minDate && endDate <= maxDate && startDate <= endDate

Check.Quick test

1 FsCheck 文档

Make sure there is a high chance that the predicate is satisfied.

关于f# - 使用 FsCheck 生成记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58615430/

相关文章:

generics - 类型推断在具有静态成员约束的泛型类型上失败

.net - 为什么在 F# 的一个方法中可以有多个 let 绑定(bind)

.net - 缺少 F# .NET Framework 控制台应用程序模板

f# - 为什么 WSDL 类型提供程序不能消除重载的歧义?

f# - FsCheck NUnit 。有条件的测试

f# - 如何覆盖 FsCheck 中所有属性的字符串生成

c# - C# 中的模式匹配 F# 中定义的类型

random - 如何为 FsCheck 创建具有固定项目列表的生成器

f# - 在 FsCheck 中生成自定义数据

c# - 如何为 FsCheck 测试生成空字符串