gpt4 book ai didi

scala - scalatest 检测到故障时如何忽略测试实用程序方法?

转载 作者:行者123 更新时间:2023-12-04 15:41:42 26 4
gpt4 key购买 nike

我在我的测试中有这个方便的方法:

  def assertFormat[T: SexpFormat](start: T, expect: Sexp): Unit = {
val sexp = start.toSexp
assert(sexp === expect, s"${sexp.compactPrint} was not ${expect.compactPrint}")
expect.convertTo[T] should be(start)
}

这基本上是运行我经常做的断言模式的便利。

不可能将其重写为 Matcher因为对 SexpFormat[T] 的隐含要求(虽然我很想知道不需要我在 MyFormat 中写类型 foo should roundTrip[MyFormat](...) 的方法)

如果此实用程序方法中的任何测试失败,scaltest 将标记 assertFormat 的内部结构。作为测试失败的原因。但我真的希望 scalatest 检测到这个方法的调用者是测试的原因。我怎样才能做到这一点?

即当前输出是
[info] - should support custom missing value rules *** FAILED ***
[info] SexpNil did not equal SexpCons(SexpSymbol(:duck),SexpCons(SexpNil,SexpNil)) nil was not (:duck nil) (FormatSpec.scala:11)
[info] org.scalatest.exceptions.TestFailedException:
[info] at org.scalatest.Assertions$class.newAssertionFailedException(Assertions.scala:529)
[info] at org.scalatest.FlatSpec.newAssertionFailedException(FlatSpec.scala:1691)
[info] at org.scalatest.Assertions$AssertionsHelper.macroAssert(Assertions.scala:502)
[info] at org.ensime.sexp.formats.FormatSpec$class.assertFormat(FormatSpec.scala:11)
[info] at org.ensime.sexp.formats.test.FamilyFormatsSpec.assertFormat(FamilyFormatsSpec.scala:151)
[info] at org.ensime.sexp.formats.test.FamilyFormatsSpec.roundtrip(FamilyFormatsSpec.scala:156)
[info] at org.ensime.sexp.formats.test.FamilyFormatsSpec$$anonfun$12.apply(FamilyFormatsSpec.scala:222)
[info] at org.ensime.sexp.formats.test.FamilyFormatsSpec$$anonfun$12.apply(FamilyFormatsSpec.scala:221)
FormatSpec.scala:11是我的 assertFormat被定义为。真正的失败在 FamilyFormatsSpec.scala:222 (这是调用另一个方便的方法 FamilyFormatsSpec.scala:156 )

最佳答案

通过采用隐式 org.scalactic.source.Position,这在 ScalaTest 3.0 中是可能的。在您的自定义断言中。每当您的 assertFormat 时,该位置将被计算(通过宏)方法被调用,该位置将被 assertFormat 中的 assert 和 matcher 表达式选取。 .这是它的外观:

import org.scalactic.source

def assertFormat[T: SexpFormat](start: T, expect: Sexp)(implicit pos: source.Position): Unit = {
val sexp = start.toSexp
assert(sexp === expect, s"${sexp.compactPrint} was not ${expect.compactPrint}")
expect.convertTo[T] should be(start)
}

下面的例子说明了它。如果类路径上有 ScalaTest 3.0,只需:将以下文件加载到 Scala REPL 中:
:paste

import org.scalatest._
import org.scalactic._
import Matchers._

case class Sexp(o: Any) {
def compactPrint: String = o.toString
def convertTo[T: SexpFormat]: Sexp = implicitly[SexpFormat[T]].convertIt(o)
override def toString = "I'm too sexp for my shirt."
}

trait SexpFormat[T] {
def convertIt(o: Any): Sexp = new Sexp(o)
}

implicit class Sexpify(o: Any) {
def toSexp: Sexp = new Sexp(o)
}

implicit def universalSexpFormat[T]: SexpFormat[T] = new SexpFormat[T] {}

def assertFormat[T: SexpFormat](start: T, expect: Sexp): Unit = {
val sexp = start.toSexp
assert(sexp === expect, s"${sexp.compactPrint} was not ${expect.compactPrint}")
expect.convertTo[T] should be(start)
}

import org.scalatest.exceptions.TestFailedException

val before = intercept[TestFailedException] { assertFormat(1, new Sexp) }

println(s"${before.failedCodeStackDepth} - This stack depth points to the assert call inside assertFormat")

import org.scalactic.source

def betterAssertFormat[T: SexpFormat](start: T, expect: Sexp)(implicit pos: source.Position): Unit = {
val sexp = start.toSexp
assert(sexp === expect, s"${sexp.compactPrint} was not ${expect.compactPrint}")
expect.convertTo[T] should be(start)
}

val after = intercept[TestFailedException] { betterAssertFormat(1, new Sexp) }

println(s"${after.failedCodeStackDepth} - This stack depth is the betterAssertFormat call itself in your test code")

它会打印:
3 - This stack depth points to the assert call inside assertFormat
4 - This stack depth is the betterAssertFormat call itself in your test code

关于scala - scalatest 检测到故障时如何忽略测试实用程序方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38284934/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com