问题描述
我想使用FsCheck(与XUnit一起)创建以下类型的记录:type QueryRequest = {Symbol: string; StartDate: DateTime; EndDate: DateTime}
,其中Symbol
限于3个选项-ORCL
,IBM
,AAPL
和StartDate
,以及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 QueryRequest
s...
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生成记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!