本文介绍了使用FsCheck生成记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用FsCheck(与XUnit一起)创建以下类型的记录:type QueryRequest = {Symbol: string; StartDate: DateTime; EndDate: DateTime},其中Symbol限于3个选项-ORCLIBMAAPLStartDate,以及EndDate限制在 2000年1月1日 2019年1月1日之间.

I'd like to use FsCheck (with XUnit) to create records of type: type QueryRequest = {Symbol: string; StartDate: DateTime; EndDate: DateTime} where Symbol is limited to 3 options - ORCL, IBM, AAPL, and StartDate and EndDate are limited to the range between January 1, 2000 and January 1, 2019.

但是,我不清楚如何进行.是否应该使用Arb.generate<T>Arb.Default或其他实用程序作为测试用例的生成和缩小的依据?

However, I'm unclear as to how proceed. Should I use Arb.generate<T> or Arb.Default or some other utility upon which to base the generation and shrinking of the test cases?

更新1

与问题产生记录相关的后续问题可在此处获得.. >

Follow-on question related to issues generating records is available 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

推荐答案

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

When you have constraints that limit the values to a small subset of all allowed values for a given type, constructing a valid value is easier and more safe than filtering.

给出...

open FsCheck
open System

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

...我们可以从为符号创建生成器开始

... we can start by creating a generator for 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

Note that Gen.choose only accepts an int range. We can work around by generating a random offset of at max the allowed date difference and then mapping back to a DateTime

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

Using those, we can construct a generator for QueryRequests...

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


FsCheck文档


FsCheck Documentation

这篇关于使用FsCheck生成记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-09 23:48