scala - 如何让 scalacheck 在带有 Seq 的类上工作?

标签 scala scalacheck

我有一个案例类,我正在尝试通过 ScalaCheck 进行测试。案例类包含其他类。

以下是类(class):

case class Shop(name: String = "", colors: Seq[Color] = Nil)
case class Color(colorName: String = "", shades: Seq[Shade] = Nil)
case class Shade(shadeName: String, value: Int)

我为每个人都有发电机

implicit def shopGen: Gen[Shop] = 
  for {
    name <- Gen.alphaStr.suchThat(_.length > 0)
    colors <- Gen.listOf(colorsGen)
  } yield Shop(name, colors)

implicit def colorsGen: Gen[Color] =
  for {
   colorName <- Gen.alphaStr.suchThat(_.length > 0)
   shades <- Gen.listOf(shadesGen)
  } yield Color(colorName, shades)

implicit def shadesGen: Gen[Shade] = 
  for {
    shadeName <- Gen.alphaStr.suchThat(_.length > 0) //**Note this**
    value <- Gen.choose(1, Int.MaxValue)
  } yield Shade(shadeName, value)

当我编写测试并简单地执行以下操作时:

  property("Shops must encode/decode to/from JSON") {
     "test" mustBe "test   
  }

我收到错误,测试挂起并在 51 次尝试后停止。我得到的错误是在 1 次成功的属性评估后放弃。 51 个评估被丢弃。

如果我从 shadesGen 中删除 Gen.alphaStr.suchThat(_.length > 0) 并将其替换为 Gen.alphaStr 那么有用。

问题

  1. 为什么 Gen.alphaStrshadesGen 有效,但 Gen.alphaStr.suchThat(_.length > 0) 却无效?
  2. 此外,当我多次运行测试(使用 Gen.alphaStr)时,有些会通过,有些则不会。这是为什么?

最佳答案

您可能会因为 listOf 的实现方式而看到此行为。它内部基于 buildableOf ,而 buildableOf 又基于 buildableOfN ,它具有以下注释:

... If the given generator fails generating a value, the complete container generator will also fail.

你的数据结构本质上是一个列表的列表,所以即使是一个糟糕的一代也会诅咒整个数据结构被丢弃。显然,大多数失败都发生在底层。这就是为什么删除 shadeName 过滤器会有所帮助。因此,为了使其工作,您应该生成更多有效的字符串。您可以将 Gen.alphaStr 更改为一些基于 nonEmptyListOf 的定制生成器,例如:

def nonemptyAlphaStr:Gen[String] = Gen.nonEmptyListOf(alphaChar).map(_.mkString)

解决此问题的另一种简单方法是使用 retryUntil 而不是 suchThat,例如:

implicit def shadesGen: Gen[Shade] =
  for {
    //shadeName <- Gen.alphaStr.suchThat(_.length > 0) //**Note this**
    shadeName <- Gen.alphaStr.retryUntil(_.length > 0)
    value <- Gen.choose(1, Int.MaxValue)
  } yield Shade(shadeName, value)

关于scala - 如何让 scalacheck 在带有 Seq 的类上工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53435893/

相关文章:

scala - 是否有针对非 Scala 程序员的 SBT 指南?

scalacheck 任意隐式和递归生成器

unit-testing - Scalacheck,大小介于 5 和 12 之间的列表的生成器

java - 在 Java 中随机生成*有趣的*字符串

scala - 为什么 SBT 给我一个类型不匹配错误?

scala - 如何在Akka中保留请求上下文数据

ScalaCheck 专门针对属性的最低成功测试

scala - 在 Circleci 上运行测试时获取文件名太长

Scala 隐式排序

string - 如何在Scala中找到两个字符串之间的最大重叠?