6

这是https://stackoverflow.com/questions/12639454/make-scalacheck-tests-deterministic中的“奖励问题” ,但没有回答:

有没有办法打印出 ScalaCheck 使用的随机种子,以便您可以重现特定的测试运行?

一个hacky 方法:包装一个随机生成器以在初始化时打印其种子并将其传递给Test.Parameters. 有更好的选择吗?

4

3 回答 3

3

到今天为止,这是可能的(参见scalacheck#263)。这里有一些很好的例子:使用带有 ScalaCheck 的种子进行确定性基于属性的测试的简单示例

简而言之,您可以这样做:

propertyWithSeed("your property", Some("seed")) =
  forAll { ??? }

当此属性失败时,将打印种子。

于 2018-08-03T07:03:43.527 回答
2

今天没有办法做到这一点。但是,它会在未来实现,见https://github.com/rickynils/scalacheck/issues/67

于 2014-02-03T10:01:40.627 回答
1

是我的回答:

奖励问题:是否有官方方法可以打印出 ScalaCheck 使用的随机种子,以便您甚至可以重现非确定性测试运行?

specs2-scalacheck版本开始4.6.0,这现在是默认行为:

给定测试文件HelloSpec

package example

import org.specs2.mutable.Specification
import org.specs2.ScalaCheck

class HelloSpec extends Specification  with ScalaCheck {
package example

import org.specs2.mutable.Specification
import org.specs2.ScalaCheck

class HelloSpec extends Specification  with ScalaCheck {
  s2"""
    a simple property       $ex1
  """

  def ex1 = prop((s: String) => s.reverse.reverse must_== "")
}

build.sbt配置:


ThisBuild / scalaVersion     := "2.13.0"
ThisBuild / version          := "0.1.0-SNAPSHOT"
ThisBuild / organization     := "com.example"
ThisBuild / organizationName := "example"

lazy val root = (project in file("."))
  .settings(
    name := "specs2-scalacheck",
    libraryDependencies ++= Seq(
      "org.specs2" %% "specs2-core" % "4.6.0",
      "org.specs2" %% "specs2-matcher-extra" % "4.6.0",
      "org.specs2" %% "specs2-scalacheck" % "4.6.0"
    ).map(_ % "test")
  )

sbt控制台运行测试时:

sbt:specs2-scalacheck> testOnly example.HelloSpec

您会得到以下输出:

[info] HelloSpec
[error]     x a simple property
[error]  Falsified after 2 passed tests.
[error]  > ARG_0: "\u0000"
[error]  > ARG_0_ORIGINAL: "猹"
[error]  The seed is X5CS2sVlnffezQs-bN84NFokhAfmWS4kAg8_gJ6VFIP=
[error]  
[error]  > '' != '' (HelloSpec.scala:11)
[info] Total for specification HelloSpec

要重现该特定运行(即使用相同的种子),您可以seed从输出中获取并使用命令行传递它scalacheck.seed

sbt:specs2-scalacheck>testOnly example.HelloSpec -- scalacheck.seed X5CS2sVlnffezQs-bN84NFokhAfmWS4kAg8_gJ6VFIP=

这会产生与以前相同的输出。

您还可以使用以下方式以编程方式设置种子setSeed

def ex1 = prop((s: String) => s.reverse.reverse must_== "").setSeed("X5CS2sVlnffezQs-bN84NFokhAfmWS4kAg8_gJ6VFIP=")

提供的另一种方法是在设置的地方Seed传递一个隐式:Parametersseed

package example

import org.specs2.mutable.Specification
import org.specs2.ScalaCheck
import org.scalacheck.rng.Seed
import org.specs2.scalacheck.Parameters

class HelloSpec extends Specification  with ScalaCheck {

  s2"""
    a simple property       $ex1
  """

  implicit val params = Parameters(minTestsOk = 1000, seed = Seed.fromBase64("X5CS2sVlnffezQs-bN84NFokhAfmWS4kAg8_gJ6VFIP=").toOption)

  def ex1 = prop((s: String) => s.reverse.reverse must_== "")
}

是有关所有这些不同方式的文档。这个博客也谈到了这一点。

于 2019-08-22T14:29:55.973 回答