【问题标题】:How to show custom failure messages in ScalaTest?如何在 ScalaTest 中显示自定义失败消息?
【发布时间】:2011-09-21 01:06:51
【问题描述】:

有人知道如何在 ScalaTest 中显示自定义失败消息吗?

例如:

NumberOfElements() should equal (5)

失败时显示以下消息:

10 不等于 5

但我想要更多描述性的信息,例如:

NumberOfElements 应该是 5。

【问题讨论】:

    标签: scala scalatest matcher


    【解决方案1】:

    您是第一个要求提供此类功能的人。实现这一目标的一种方法是使用 withClue。比如:

    withClue("NumberOfElements: ") { NumberOfElements() should be (5) }
    

    这应该会给你这个错误消息:

    NumberOfElements: 10 不等于 5

    如果你想完全控制消息,你可以编写一个自定义匹配器。或者你可以使用一个断言,像这样:

    assert(NumberOfElements() == 5, "NumberOfElements should be 5")
    

    您能否详细说明您的用例是什么?为什么 10 不等于 5 不符合标准,您多久有过这种需求?

    这是您要求的类型:

    scala> import org.scalatest.matchers.ShouldMatchers._
    import org.scalatest.matchers.ShouldMatchers._
    
    scala> withClue ("Hi:") { 1 + 1 should equal (3) }
    org.scalatest.TestFailedException: Hi: 2 did not equal 3
    at org.scalatest.matchers.Matchers$class.newTestFailedException(Matchers.scala:150)
    at org.scalatest.matchers.ShouldMatchers$.newTestFailedException(ShouldMatchers.scala:2331)
    
    
    scala> class AssertionHolder(f: => Any) {
         |   def withMessage(s: String) {
         |     withClue(s) { f }
         |   }
         | }
    defined class AssertionHolder
    
    scala> implicit def convertAssertion(f: => Any) = new AssertionHolder(f)
    convertAssertion: (f: => Any)AssertionHolder
    
    scala> { 1 + 1 should equal (3) } withMessage ("Ho:")
    org.scalatest.TestFailedException: Ho: 2 did not equal 3
    at org.scalatest.matchers.Matchers$class.newTestFailedException(Matchers.scala:150)
    at org.scalatest.matchers.ShouldMatchers$.newTestFailedException(ShouldMatchers.scala:2331)
    

    所以你可以这样写:

    { NumberOfElements() should be (5) } withMessage ("NumberOfElements:")
    

    【讨论】:

    • 在某些情况下,我必须在 it() 测试中放置多个断言,并且存在多个整数比较。通过查看日志并不清楚哪个断言失败。
    • 但是 withClue 指定它的方式是不可读的。没有办法在最后指定消息吗?
    • 最后无法使用匹配器的 DSL,但您可以编写一个方法,将 withClue 参数以相反的顺序放置。我将在答案中添加一个示例。
    【解决方案2】:

    自 2011 年以来的新方式:MatchersAppendedClue1 特征。此外,对于集合大小,还有一些默认消息。

    import org.scalatest.{AppendedClues, Matchers, WordSpec}
    
    class SomeTest extends WordSpec with Matchers with AppendedClues {
    
      "Clues" should {
        "not be appended" when {
          "assertions pass" in {
            "hi" should equal ("hi") withClue "Greetings scala tester!"
          }
        }
        "be appended" when {
          "assertions fail"  in {
            1 + 1 should equal (3) withClue ", not even for large values of 1!"
          }
        }
        "not be needed" when {
          "looking at collection sizes" in {
            val list = List(1, 2, 3)
            list should have size 5
          }
        }
      }
    }
    

    输出如下所示:

    SomeTest:
    Clues
      should not be appended
      - when assertions pass
      should be appended
      - when assertions fail *** FAILED ***
        2 did not equal 3, not even for large values of 1! (SomeTest.scala:15)
      should not be needed
      - when looking at collection sizes *** FAILED ***
        List(1, 2, 3) had size 3 instead of expected size 5 (SomeTest.scala:21)
    

    请注意,List 大小消息不适用于具有长 .toString 输出的列表。

    请参阅scaladoc 了解更多信息。


    1 我猜AppendedClues trait 是受到这个问题的启发,接受的答案的 Bill Venners 是这个 trait 的作者。

    【讨论】:

      【解决方案3】:

      您也可以使用withClue,而不需要导入任何内容或将其添加到测试类中:

      withClue(s"Expecting distinct elements: ${elements.toList}") { elements.length shouldBe 3 }
      

      这是从Assertions类导入的:org.scalatest.Assertions#withClue

      【讨论】:

      • 在接受的答案之上添加了什么?
      猜你喜欢
      • 2012-02-27
      • 1970-01-01
      • 1970-01-01
      • 2012-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      相关资源
      最近更新 更多