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

标签 scala unicode specs2 scalacheck

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

  • 有什么办法可以改变 ScalaCheck 生成的案例数量?
  • 如何生成包含一些 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)
    }
    

    编辑

    我才意识到还有一个问题:
  • ScalaCheck 经常在没有生成 100 个测试用例的情况下放弃

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

    最佳答案

    “在 47 次测试后放弃”错误意味着您的条件(包括 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)
    

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

    关于scala - 如何减少 ScalaCheck 生成的测试用例的数量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30365417/

    相关文章:

    scala - Play +specs2+scalacheck?

    scala - 确保 ScalaTest 不并行运行

    scala 以格式保存到数组

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

    scala - 当涉及特征时,Mockito 会忽略我的 Specs2 加糖验证步骤

    specs2 - Specs2 类中未解析的符号 s2

    scala - 处理 Scala 宏中的按名称参数

    c++ - Visual C++ argv 问题

    C# 无法将类型 'string' 隐式转换为 'System.IO.StreamReader

    unicode - 组合任意 Unicode 符号或具有负宽度的 Unicode 字符