Scalacheck,大小 5 到 12 之间的列表生成器

问题描述 投票:0回答:2

我可以找到许多设置生成器最大尺寸的示例,但是如何生成最小和最大长度之间的列表?

unit-testing scalatest scalacheck property-based-testing
2个回答
16
投票

生成器的一个巧妙属性是它们是可组合的,因此您可以简单地使用

listOfN
生成器来组合列表长度的生成器。

for {
  numElems <- Gen.choose(5, 12)
  elems <- Gen.listOfN(numElems, elemGenerator)
} yield elems

3
投票

我在这里唤醒鬼魂,但万一有人出现:

根据我对已接受答案的评论,该解决方案随机决定 5 到 12 之间的最大长度,但在这种情况下,生成列表的实际大小仍然可以是 0(零)或低于 5 的任何值。

我认为以下内容符合OP所描述的内容:

Gen
  .listOfN(12, elemGenerator)
  .suchThat(_.size >= 5)

如果有一个 API 可以方便地生成这个,或者说一个精确大小的列表,那就太酷了,

N

更新(2022/12/22)...因为我意识到我从未真正回答过OP的问题(并由最近的评论提示):

def listOf[E](min: Int, max: Int, factor: Int = 4, retries: Int = 10000)(implicit gen: Gen[E]): Gen[List[E]] = for {
  size <- Gen.choose(min, max)
  list <- Gen.listOfN(factor * size, gen).retryUntil(_.size >= min, retries).flatMap(_.take(size))
} yield list

factor
是为了增加在 10,000 尝试(ScalaCheck 的默认值)内生成大于大小
min
的列表的可能性;也许太大的
factor
会偏离
min
大小的列表。

或者,如果您喜欢猫和朋友 (cats-scalacheck):

def listOf[E](min: Int, max: Int)(implicit gen: Gen[E]): Gen[List[E]] = for {
  size <- Gen.choose(min, max)
  list <- List.fill(size)(gen).sequence
} yield list

我无法证明 cats-scalacheck 中发生了什么;也许他们也使用

suchThat
retryUntil

© www.soinside.com 2019 - 2024. All rights reserved.