【问题标题】:How can I reduce the number of test cases ScalaCheck generates?如何减少 ScalaCheck 生成的测试用例的数量?
【发布时间】:2015-05-21 05:40:52
【问题描述】:

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

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

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

例如,我想生成大约 10 个包含字母数字和 Unicode 字符的随机字符串。然而,这段代码总是生成 100 个随机字符串,并且它们是严格基于字母字符的:

"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 个测试用例的情况下放弃

当然,我不想要 100,但显然我的代码正试图生成一组过于复杂的规则。上次运行时,我看到“47 次测试后放弃。”

【问题讨论】:

    标签: scala unicode specs2 scalacheck


    【解决方案1】:

    “在 47 次测试后放弃”错误意味着您的条件(包括 suchThat 谓词和 ==&gt; 部分)过于严格。幸运的是,将它们烘焙到您的生成器中通常并不难,在您的情况下,您可以编写类似这样的内容(这也解决了选择任意字符的问题,而不仅仅是字母数字字符):

    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)
    

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

    【讨论】:

    • 谢谢!很有帮助。
    • 另一个问题出现了......你的例子(上面)包括几乎所有 all unicode 字符(主要是亚洲)。我如何限制它以生成更多面向盎格鲁的字符集,也许是拉丁语加上一些北欧/日耳曼字符......?如果您有任何想法,我将不胜感激......
    • 对,我的答案中的arbitrary[Char] 是从所有字符中挑选出来的。您可以将其替换为由Gen 上的组合子构建的自定义Gen[Char]。但请注意,如果您试图确认异常值不会导致程序崩溃,那么过多地限制测试用例可能会适得其反。
    • 请注意,您可以使用buildableOfN 而不是sequence 更直接地编写此代码——我刚刚更新了答案。
    猜你喜欢
    • 2011-11-23
    • 1970-01-01
    • 2023-01-16
    • 2022-06-15
    • 2013-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多