关于scala:在specs2框架中,为什么使用Scope会阻止执行forAll量词?

In the specs2 framework, why does using a Scope prevent execution of a forAll quantifier?

在下面的代码中,如何使Specs2执行第一个测试?"打印内容"测试应在失败时通过。由于new Scope

forAll()部分中的代码未执行。

println语句仅用于跟踪输出。如果您看到任何以" one"开头的行,请告诉我。

空的Scope仅用于演示问题。这是我在Scope

中实际使用变量的代码中精简的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import org.scalacheck.Gen
import org.scalacheck.Prop._
import org.specs2.ScalaCheck
import org.specs2.mutable.Specification
import org.specs2.specification.Scope

class TestingSpec extends Specification with ScalaCheck {
 "sample test" should {
   "print ones" in new Scope {
      println("The first test passes, but should fail")
      forAll(Gen.posNum[Int]) { (x: Int) =>
          println("one:" + x)
          (0 < x) mustNotEqual true
      }
    }

   "print twos" in {
      println("The second test passes and prints twos")
      forAll(Gen.posNum[Int]) { (x: Int) =>
        println("two:" + x)
        (0 < x) mustEqual true
      }
    }
  }
}

这是我的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
sbt> testOnly TestingSpec
The second test passes and prints twos
The first test passes, but should fail
two: 1
two: 2
two: 1
    ...
two: 50
two: 34
two: 41
[info] TestingSpec
[info]
[info] sample test should
[info]   + print ones
[info]   + print twos
[info]
[info] Total for specification TestingSpec
[info] Finished in 96 ms
[info] 2 examples, 101 expectations, 0 failure, 0 error
[info]
[info] Passed: Total 2, Failed 0, Errors 0, Passed 2
[success] Total time: 3 s, completed Apr 28, 2015 3:14:15 PM

P.S。我将项目依赖项从2.4.15版本更新为specs2 3.5。仍然有这个问题...


这是因为您放置在Scope中的任何内容在发生故障时都必须引发异常。除非您执行它,否则ScalaCheck Prop不会执行任何操作,因此您的示例将始终通过。

解决方法是使用以下隐式示例将Prop转换为specs2 Result

1
2
3
4
5
6
import org.specs2.execute._

implicit class RunProp(p: Prop) {
  def run: Result =
    AsResult(p)
}

然后

1
2
3
4
5
6
7
"print ones" in new Scope {
  println("The first test passes, but should fail")
   forAll(Gen.posNum[Int]) { (x: Int) =>
     println("one:" + x)
      (0 < x) mustNotEqual true
   }.run
}