3

在下面的代码中,如何让 Specs2 执行第一个测试?“打印的”测试在它应该失败时通过。由于. forAll()_new Scope

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

Scope只是为了说明问题。这是从我实际使用变量的代码中剥离出来的Scope

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
      } 
    } 
  }
}

这是我的输出:

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

PS 我将我的项目依赖项从版本 2.4.15 更新到 specs2 3.5。还是有这个问题...

4

2 回答 2

4

Scope这是因为当出现故障时,您放入的任何内容都必须抛出异常。ScalaCheckProp不会做任何事情,除非您执行它,因此您的示例将始终通过。

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

import org.specs2.execute._

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

然后

"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 
} 
于 2015-04-28T22:13:05.880 回答
0

我发现的另一种方法是开始,Prop然后将您的定义Scope如下:


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

与@Eric 的回答相比,我更喜欢这种方法,因为首先您不需要隐式类,其次您不必调用run可能会忘记的方法。

于 2021-06-04T08:29:58.807 回答