如何在 ScalaTest 中显示自定义失败消息?

Posted

技术标签:

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

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

例如:

NumberOfElements() should equal (5)

失败时显示以下消息:

10 不等于 5

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

NumberOfElements 应该是 5。

【问题讨论】:

【参考方案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

【讨论】:

在接受的答案之上添加了什么?

以上是关于如何在 ScalaTest 中显示自定义失败消息?的主要内容,如果未能解决你的问题,请参考以下文章

Mongo Shell 显示添加的文档,但在 Scalatest 中断言失败

ScalaTest:在失败的期货中断言异常(非阻塞)

如何在sbt测试中仅显示失败的测试?

joomla 2.5!自定义登录失败通知?

如何在登录失败时显示错误消息?

如何在 Web API Post 方法中返回自定义消息