ScalaCheck,调用 Test.check 或 Test.checkProperties 时的不同行为
ScalaCheck, different behaviour when calling Test.check or Test.checkProperties
我有以下代码使用 ScalaCheck 属性来测试一些 class
package quickcheck.tests
import org.scalacheck.Arbitrary._
import org.scalacheck.Gen._
import org.scalacheck.Prop._
import org.scalacheck._
import org.scalacheck.util.ConsoleReporter
class Heap
{
}
object Heap
{
val empty = new Heap
def insert(i: Int, h: Heap) = new Heap
}
class TestCheck extends Properties("Heap")
{
lazy val genHeap: Gen[Heap] =
{
def sizedHeap(size: Int): Gen[Heap] =
{
if (size <= 0)
Heap.empty
else
for
(
i <- arbitrary[Int] suchThat(_ > Int.MinValue);
s <- choose(0, size);
h <- sizedHeap(s)
)
yield
Heap.insert(i, h)
}
Gen.sized[Heap](sizedHeap)
}
implicit lazy val arbHeap: Arbitrary[Heap] = Arbitrary(genHeap)
property("test1") = forAll
{
(h: Heap) => true
}
property("test2") = forAll
{
(h1: Heap, h2: Heap, n: Int) => true
}
}
object MyTest extends App
{
println("*** TEST 1")
val checkHeap = new TestCheck
Test.checkProperties(Test.Parameters.default.withTestCallback(ConsoleReporter(1)),
checkHeap)
println("*** TEST 2")
val checkHeap2 = new TestCheck
checkHeap2.check
println("*** TEST 3")
val checkHeap3 = new TestCheck
Test.check(Test.Parameters.default.withTestCallback(ConsoleReporter(1)), checkHeap)
}
如果我 运行 通过 ScalaCheck Test
class 如果我使用方法 Test.checkProperties
或方法 Test.check
.[=24 我会得到不同的结果=]
这是我得到的输出:
*** TEST 1
+ Heap.test1: OK, passed 100 tests.
+ Heap.test2: OK, passed 100 tests.
*** TEST 2
+ Heap.test1: OK, passed 100 tests.
+ Heap.test2: OK, passed 100 tests.
*** TEST 3
! Gave up after only 40 passed tests. 202 tests were discarded.
我的问题是为什么 TEST1 给出的结果与 TEST3 不同。
如果我删除 suchThat
过滤器并将 for
语句保留在 sizeHead
方法中,如下所示:
for
(
i <- arbitrary[Int]
s <- choose(0, size);
h <- sizedHeap(s)
)
yield
Heap.insert(i, h)
我得到以下结果:
*** TEST 1
+ Heap.test1: OK, passed 100 tests.
+ Heap.test2: OK, passed 100 tests.
*** TEST 2
+ Heap.test1: OK, passed 100 tests.
+ Heap.test2: OK, passed 100 tests.
*** TEST 3
+ OK, passed 100 tests.
这是错误还是正确的行为?请记住,ScalaTest Checkers.check
使用 Test.check
。
你会得到不同的结果,因为你在做不同的事情。您的前两个测试 - effectively the same - 分别检查所有属性,而您的第三个测试测试所有属性 就好像它们是单个 属性.
看一下Test.check
和Test.checkProperties
的签名:前者采用单个Prop
,而后者采用Properties
容器。
在 scalacheck 1.12 中 Properties
继承自 Prop
;如果您将 Properties
作为 Prop
传递,您会得到 新的 属性,即 tests whether all contained properties hold。结果是您使用 单个 检查配置(即生成器、迭代限制等)测试所有 TestCheck
属性,并且自然地检查配置在某个时候耗尽.
所以是的,这是预期的行为。当然,这绝对令人困惑,因此 scalacheck 1.13 删除了此功能:Properties
不再继承自 Prop
;您的示例将不再在 scalacheck 1.13 上编译。
我有以下代码使用 ScalaCheck 属性来测试一些 class
package quickcheck.tests
import org.scalacheck.Arbitrary._
import org.scalacheck.Gen._
import org.scalacheck.Prop._
import org.scalacheck._
import org.scalacheck.util.ConsoleReporter
class Heap
{
}
object Heap
{
val empty = new Heap
def insert(i: Int, h: Heap) = new Heap
}
class TestCheck extends Properties("Heap")
{
lazy val genHeap: Gen[Heap] =
{
def sizedHeap(size: Int): Gen[Heap] =
{
if (size <= 0)
Heap.empty
else
for
(
i <- arbitrary[Int] suchThat(_ > Int.MinValue);
s <- choose(0, size);
h <- sizedHeap(s)
)
yield
Heap.insert(i, h)
}
Gen.sized[Heap](sizedHeap)
}
implicit lazy val arbHeap: Arbitrary[Heap] = Arbitrary(genHeap)
property("test1") = forAll
{
(h: Heap) => true
}
property("test2") = forAll
{
(h1: Heap, h2: Heap, n: Int) => true
}
}
object MyTest extends App
{
println("*** TEST 1")
val checkHeap = new TestCheck
Test.checkProperties(Test.Parameters.default.withTestCallback(ConsoleReporter(1)),
checkHeap)
println("*** TEST 2")
val checkHeap2 = new TestCheck
checkHeap2.check
println("*** TEST 3")
val checkHeap3 = new TestCheck
Test.check(Test.Parameters.default.withTestCallback(ConsoleReporter(1)), checkHeap)
}
如果我 运行 通过 ScalaCheck Test
class 如果我使用方法 Test.checkProperties
或方法 Test.check
.[=24 我会得到不同的结果=]
这是我得到的输出:
*** TEST 1
+ Heap.test1: OK, passed 100 tests.
+ Heap.test2: OK, passed 100 tests.
*** TEST 2
+ Heap.test1: OK, passed 100 tests.
+ Heap.test2: OK, passed 100 tests.
*** TEST 3
! Gave up after only 40 passed tests. 202 tests were discarded.
我的问题是为什么 TEST1 给出的结果与 TEST3 不同。
如果我删除 suchThat
过滤器并将 for
语句保留在 sizeHead
方法中,如下所示:
for
(
i <- arbitrary[Int]
s <- choose(0, size);
h <- sizedHeap(s)
)
yield
Heap.insert(i, h)
我得到以下结果:
*** TEST 1
+ Heap.test1: OK, passed 100 tests.
+ Heap.test2: OK, passed 100 tests.
*** TEST 2
+ Heap.test1: OK, passed 100 tests.
+ Heap.test2: OK, passed 100 tests.
*** TEST 3
+ OK, passed 100 tests.
这是错误还是正确的行为?请记住,ScalaTest Checkers.check
使用 Test.check
。
你会得到不同的结果,因为你在做不同的事情。您的前两个测试 - effectively the same - 分别检查所有属性,而您的第三个测试测试所有属性 就好像它们是单个 属性.
看一下Test.check
和Test.checkProperties
的签名:前者采用单个Prop
,而后者采用Properties
容器。
在 scalacheck 1.12 中 Properties
继承自 Prop
;如果您将 Properties
作为 Prop
传递,您会得到 新的 属性,即 tests whether all contained properties hold。结果是您使用 单个 检查配置(即生成器、迭代限制等)测试所有 TestCheck
属性,并且自然地检查配置在某个时候耗尽.
所以是的,这是预期的行为。当然,这绝对令人困惑,因此 scalacheck 1.13 删除了此功能:Properties
不再继承自 Prop
;您的示例将不再在 scalacheck 1.13 上编译。