Scalatest – pretty error message outputs?

huangapple go评论48阅读模式
英文:

Scalatest - pretty error messsage outputs?

问题

当使用 scalatest 时,如果需要比较 case 类集合,且其中一个参数与预期不同,输出结果通常难以阅读,需要将其复制到记事本并适当格式化以找出问题所在。

是否有一种方法可以覆盖 scalatest 的默认输出,以生成更可读的输出?

例如:

case class Test(a: String, b: String, c: String)

"lists" should "match" in {
  val l1 = List(
    Test("a", "b", "c"),
    Test("d", "e", "f"),
    Test("g", "h", "i")
  )

  val l2 = List(
    Test("a", "b", "c"),
    Test("d", "E", "f"),
    Test("g", "h", "i")
  )

  l1 should contain theSameElementsAs l2
}

输出:

lists
- should match *** FAILED ***
  List(Test("a", "b", "c"), Test("d", "e", "f"), Test("g", "h", "i")) did not contain the same elements as List(Test("a", "b", "c"), Test("d", "E", "f"), Test("g", "h", "i")) (Test.scala:52)

这不是太糟糕,因为 Test case 类不太大。但如果 case 类很大,输出可能会变得非常混乱。

我希望的是这样的输出:

lists
- should match *** FAILED ***
  List(
    Test("a", "b", "c"),
    Test("d", "e", "f"),
    Test("g", "h", "i")
  )
  did not contain the same elements as
  List(
    Test("a", "b", "c"),
    Test("d", "E", "f"),
    Test("g", "h", "i")
  )
  (Test.scala:52)

如果能告诉我差异在哪里会更好。

除了更改测试框架之外,是否可以在 scalatest 中实现这个目标?

英文:

When using scalatest, any time we have to compare collections of case classes, if one of the parameters is different from expected, the output is unreadable and we have to put it in a notepad and format it correctly in order to figure out what's wrong.

Is there any way to override the default output of scalatest into something more readable?

For example:

  case class Test(a: String, b: String, c: String)

  "lists" should "match" in {
    val l1 = List(
      Test("a", "b", "c"),
      Test("d", "e", "f"),
      Test("g", "h", "i")
    )

    val l2 = List(
      Test("a", "b", "c"),
      Test("d", "E", "f"),
      Test("g", "h", "i")
    )

    l1 should contain theSameElementsAs l2
  }

output:

lists
- should match *** FAILED ***
  List(Test("a", "b", "c"), Test("d", "e", "f"), Test("g", "h", "i")) did not contain the same elements as List(Test("a", "b", "c"), Test("d", "E", "f"), Test("g", "h", "i")) (Test.scala:52)

This isn't as bad, since the Test case class isn't too large. But if its a big case class, the output can get very ugly.

What I want is something like this:

lists
- should match *** FAILED ***
  List(
    Test("a", "b", "c"),
    Test("d", "e", "f"),
    Test("g", "h", "i")
  )
  did not contain the same elements as
  List(
    Test("a", "b", "c"),
    Test("d", "E", "f"),
    Test("g", "h", "i")
  )
  (Test.scala:52)

Even better if I can have it tell me what is different.

Besides switching test frameworks, is this something doable with scalatest?

答案1

得分: 4

Sure, here is the translated code part you requested:

使用 ScalaTest 来考虑 [diffx-scala][1]

```scala
import org.scalatest._
import flatspec._
import com.softwaremill.diffx.scalatest.DiffShouldMatcher._
import com.softwaremill.diffx.generic.AutoDerivation

class ExampleSpec extends AnyFlatSpec with AutoDerivation {

  case class Test(a: String, b: String, c: String)

  "lists" should "match" in {
    val l1 = List(
      Test("a", "b", "c"),
      Test("d", "e", "f"),
      Test("g", "h", "i")
    )

    val l2 = List(
      Test("a", "b", "c"),
      Test("d", "E", "f"),
      Test("g", "h", "i")
    )

    l1 shouldMatchTo (l2)
  }
}

这段代码使用了 ScalaTest 运行 diffx-scala 的测试。希望这对你有帮助。


<details>
<summary>英文:</summary>

Consider [diffx-scala][1] with ScalaTest:

import org.scalatest._
import flatspec._
import com.softwaremill.diffx.scalatest.DiffShouldMatcher._
import com.softwaremill.diffx.generic.AutoDerivation

class ExampleSpec extends AnyFlatSpec with AutoDerivation {

case class Test(a: String, b: String, c: String)

"lists" should "match" in {
val l1 = List(
Test("a", "b", "c"),
Test("d", "e", "f"),
Test("g", "h", "i")
)

val l2 = List(
  Test(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;),
  Test(&quot;d&quot;, &quot;E&quot;, &quot;f&quot;),
  Test(&quot;g&quot;, &quot;h&quot;, &quot;i&quot;)
)

l1 shouldMatchTo(l2)

}
}


which gives pretty printed matching error output:

ExampleSpec:
lists

  • should match *** FAILED ***
    Matching error:
    List(
    0: Test(
    a: a,
    b: b,
    c: c),
    1: Test(
    a: d,
    b: e -> E,
    c: f),
    2: Test(
    a: g,
    b: h,
    c: i)) (MySuite.scala:34)
    Execution took 0.19s
    1 tests, 1 failed

Related question: https://stackoverflow.com/questions/60025869/case-class-difference-with-field-names-on-matcher-failure





  [1]: https://diffx-scala.readthedocs.io/en/latest/test-frameworks/scalatest.html

</details>



huangapple
  • 本文由 发表于 2023年4月1日 00:59:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75900989.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定