How to show custom failure messages in ScalaTest?

家住魔仙堡 提交于 2019-12-02 17:22:15

You're the first to ask for such a feature. One way to achieve this is with withClue. Something like:

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

That should get you this error message:

NumberOfElements: 10 was not equal to 5

If you want to control the message completely you can write a custom matcher. Or you could use an assertion, like this:

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

Can you elaborate on what your use case is? Why is it that 10 did not equal 5 is not up to snuff, and how often have you had this need?

Here's the kind of thing you're requesting:

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)

So this way you can write:

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

New way since 2011: Matchers and AppendedClue traits. Also, for collection sizes, there are some default messages.

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

Output looks like this:

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)

Note that the List size message isn't great for lists with long .toString output.

See the scaladoc for more information.

You can also use withClue without importing anything or adding it to the test class:

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

This is imported from Assertions class: org.scalatest.Assertions#withClue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!