如何减少 ScalaCheck 生成的测试用例数量?

How can I reduce the number of test cases ScalaCheck generates?

我正在尝试解决两个 ScalaCheck (+ specs2) 问题:

  1. 有什么方法可以改变 ScalaCheck 生成的案例数吗?

  2. 如何生成包含一些 Unicode 字符的字符串?

例如,我想生成大约 10 个 运行dom 字符串,其中包括字母数字字符和 Unicode 字符。但是,此代码始终生成 100 个 运行dom 字符串,并且它们严格基于字母字符:

"make a random string" in {
    def stringGenerator = Gen.alphaStr.suchThat(_.length < 40)
    implicit def randomString: Arbitrary[String] = Arbitrary(stringGenerator)

    "the string" ! prop { (s: String) => (s.length > 20 && s.length < 40) ==> { println(s); success; } }.setArbitrary(randomString)
}

编辑

我刚刚意识到还有一个问题:

  1. ScalaCheck 经常在未生成 100 个测试用例的情况下放弃

G运行ted 我不想要 100,但显然我的代码试图生成一组过于复杂的规则。上次是运行,我看到"gave up after 47 tests."

"gave up after 47 tests" 错误意味着您的条件(包括 suchThat 谓词和 ==> 部分)过于严格。幸运的是,将它们融入你的生成器通常并不难,在你的情况下你可以写这样的东西(它也解决了选择任意字符的问题,而不仅仅是字母数字字符):

val stringGen: Gen[String] = Gen.chooseNum(21, 40).flatMap { n =>
  Gen.buildableOfN[String, Char](n, arbitrary[Char])
}

在这里我们选择所需范围内的任意长度,然后选择该数量的任意字符并将它们连接成一个字符串。

您还可以增加 maxDiscardRatio 参数:

import org.specs2.scalacheck.Parameters
implicit val params: Parameters = Parameters(maxDiscardRatio = 1024)

但这通常不是一个好主意 — 如果您丢弃大部分生成的值,您的测试将花费更长的时间,并且重构您的生成器通常会更干净、更快。

您还可以通过设置适当的参数来减少测试用例的数量:

implicit val params: Parameters = Parameters(minTestsOk = 10)

但是,除非您有充分的理由这样做,否则我建议您相信默认设置。