我想知道为什么需要Arbitrary,因为自动化属性测试需要属性定义,比如
val prop = forAll(v: T => check that property holds for v)
Run Code Online (Sandbox Code Playgroud)
和价值v发电机.用户指南说您可以为自定义类型创建自定义生成器(例如,树的生成器).然而,它并没有解释为什么你需要最重要的仲裁.
这是一本手册
implicit lazy val arbBool: Arbitrary[Boolean] = Arbitrary(oneOf(true, false))
Run Code Online (Sandbox Code Playgroud)
要获得对您自己的类型T的支持,您需要定义一个类型为Arbitrary [T]的隐式def或val.使用工厂方法Arbitrary(...)创建Arbitrary实例.此方法采用Gen [T]类型的一个参数并返回Arbitrary [T]的实例.
它清楚地表明我们需要在Gen之上的任意.但任意的理由并不令人满意
任意生成器是ScalaCheck在为属性参数生成值时使用的生成器.
IMO,要使用生成器,您需要导入它们而不是将它们包装到仲裁中!否则,我们可以争辩说我们需要将仲裁包装到其他东西中以使它们可用(等等无限期地无限地包装包装器).
您还可以解释如何arbitrary[Int]
将参数类型转换为生成器.这很奇怪,我觉得这些是相关的问题.
在尝试使用ScalaCheck和ScalaTest编写测试时,我遇到了一个令人讨厌的异常.这是我的依赖:
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "2.2.6" % "test",
"org.scalacheck" %% "scalacheck" % "1.13.0" % "test"
)
Run Code Online (Sandbox Code Playgroud)
这是我的测试:
import org.scalatest.PropSpec
import org.scalatest.prop.Checkers
class MyPropSpec extends PropSpec with Checkers {
property("List.concat") {
check((a: List[Int], b: List[Int]) => a.size + b.size == (a ::: b).size)
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试运行这个时,我得到:
DeferredAbortedSuite:
Exception encountered when attempting to run a suite with class name: org.scalatest.DeferredAbortedSuite *** ABORTED ***
java.lang.IncompatibleClassChangeError: Implementing class
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368) …
Run Code Online (Sandbox Code Playgroud) 我试图在ScalaCheck中生成可选参数,但没有成功.
似乎没有直接机制.Gen.containerOf[Option, Thing](thingGenerator)
失败,因为它无法找到隐含的Buildable[Thing, Option]
.
我试过了
for {
thing <- Gen.listOfN[Thing](1, thingGenerator)
} yield thing.headOption
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为listOfN
产生一个总长度为N的列表.结果我总是得到一个Some[Thing]
.类似地,listOf1
不起作用,因为(a)它不产生空列表,而且(b)它效率低,因为我不能设置元素数量的最大限制.
我怎样才能生成Option[Thing]
包含Nones的内容?
编辑:我找到了解决方案,但它并不简洁.有比这更好的方法吗?
for {
thing <- for {
qty <- Gen.choose(0,1)
things <- Gen.listOfN[Thing](qty, thingGenerator)
} yield things.headOption
} yield thing
Run Code Online (Sandbox Code Playgroud)
编辑2:我将此概括为
def optional[T](g: Gen[T]) =
for (qty <- Gen.choose(0, 1); xs <- Gen.listOfN[T](qty, g)) yield xs.headOption
Run Code Online (Sandbox Code Playgroud)
所以我不必多次写它.但肯定这已经在图书馆了,我只是错过了它?
考虑以下类别定义:
trait Category[~>[_, _]] {
def id[A]: A ~> A
def compose[A, B, C](f: A ~> B)(g: B ~> C): A ~> C
}
Run Code Online (Sandbox Code Playgroud)
这是一元函数的实例:
object Category {
implicit def fCat = new Category[Function1] {
def id[A] = identity
def compose[A, B, C](f: A => B)(g: B => C) = g.compose(f)
}
}
Run Code Online (Sandbox Code Playgroud)
现在,类别受到一些法律的约束.关于composition(.
)和identity(id
):
forall f: categoryArrow -> id . f == f . id == f
Run Code Online (Sandbox Code Playgroud)
我想用ScalaCheck测试一下.让我们尝试整数函数:
"Categories" should {
import Category._
val intG = …
Run Code Online (Sandbox Code Playgroud) 我想暂时在我的specs2测试套件中进行ScalaCheck属性测试,以便于调试.现在,每次重新运行测试套件时都会生成不同的值,这会使调试变得令人沮丧,因为您不知道观察到的行为的变化是由代码更改引起的,还是仅仅是由生成的不同数据引起的.
我怎样才能做到这一点?是否有正式的方法来设置ScalaCheck使用的随机种子?
我正在使用sbt
运行测试套件.
奖金的问题:是否有一个正式的方式打印出由ScalaCheck使用的随机种子,这样就可以重现即使是非确定性的试运行?
UserGuide scalacheck项目的提到大小的发电机.解释代码
def matrix[T](g:Gen[T]):Gen[Seq[Seq[T]]] = Gen.sized {size =>
val side = scala.Math.sqrt(size).asInstanceOf[Int] //little change to prevent compile-time exception
Gen.vectorOf(side, Gen.vectorOf(side, g))
}
Run Code Online (Sandbox Code Playgroud)
没有为我解释.经过一番探索后,我了解到生成序列的长度并不依赖于生成器的实际大小(Gen对象中的resize方法根据javadoc"创建生成器的大小调整版本"(也许这意味着不同的东西?)).
val g = Gen.choose(1,5)
val g2 = Gen.resize(15, g)
println(matrix(g).sample) // (1)
println(matrix(g2).sample) // (2)
//1,2 produce Seq with same length
Run Code Online (Sandbox Code Playgroud)
你能解释一下我错过了什么,并举例说明你如何在测试代码时使用它们?
我正在尝试使用Scalacheck生成随机数据.我有一个包含许多属性的case类的层次结构.我到目前为止找到填充案例类的唯一方法是这样的:
case class Data(a: String,
b: String,
c: String)
val genLigneDecompte: Gen[Data] = for {
ag <- Gen.alphaStr
bg <- Gen.alphaStr
cg <- Gen.alphaStr
} yield Data(
a = ag,
b = bg,
c = cg
)
Run Code Online (Sandbox Code Playgroud)
对于具有10-20个属性的案例类,这非常繁琐.我想知道是否有办法以某种方式自动化它...
我看到scalacheck似乎是一个非常明显的错误,如果真的存在,我无法看到人们如何将它用于递归数据结构.
StackOverflowError
在构造Arbitrary
值时,此程序在scalacheck接管之前失败.请注意,s 的Tree
类型和生成器Tree
是从这个scalacheck教程中逐字记录的.
package treegen
import org.scalacheck._
import Prop._
class TreeProperties extends Properties("Tree") {
trait Tree
case class Node(left: Tree, right: Tree) extends Tree
case class Leaf(x: Int) extends Tree
val ints = Gen.choose(-100, 100)
def leafs: Gen[Leaf] = for {
x <- ints
} yield Leaf(x)
def nodes: Gen[Node] = for {
left <- trees
right <- trees
} yield Node(left, right)
def trees: Gen[Tree] = Gen.oneOf(leafs, nodes)
implicit lazy …
Run Code Online (Sandbox Code Playgroud) 有没有办法让SBT重新运行测试套件最后一次运行失败的测试?例如,如果我运行sbt test
并且20次测试中有3次运行失败,是否有任何命令我可以运行让SBT重新运行那些失败的3个测试?
具体来说,我正在使用Scala Test和Scala Check来测试我通过SBT运行的测试.
我有一个包含很多Scalacheck生成器的项目正在获取GeneratorDrivenPropertyCheckFailedException,并显示消息"在0次成功的属性评估后放弃.2个评估被丢弃了."
我想让它尝试评估它多次像500(默认值)会好,但我没有看到我的配置覆盖实际使用.
我将此代码添加到测试类中,我仍然得到完全相同的消息.我试过'sbt clean'只是为了确保那里没有发生奇怪的事情.
implicit override val generatorDrivenConfig = PropertyCheckConfig(minSuccessful = 1, maxDiscarded = 500, workers = 1)
Run Code Online (Sandbox Code Playgroud)
为什么我的Scalacheck/Scalatest PropertyCheckConfig被忽略了?
我正在使用Scalatest 2.2.1与Scalacheck 1.12.1和Scala 2.10.4