¿Cómo mostrar mensajes de error personalizados en ScalaTest?


86

¿Alguien sabe cómo mostrar un mensaje de error personalizado en ScalaTest?

Por ejemplo:

NumberOfElements() should equal (5)

Muestra el siguiente mensaje cuando falla:

10 no es igual a 5

Pero quiero un mensaje más descriptivo como:

NumberOfElements debe ser 5.

Respuestas:


101

Eres el primero en solicitar esta función. Una forma de lograrlo es con withClue. Algo como:

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

Eso debería darte este mensaje de error:

NumberOfElements: 10 no es igual a 5

Si desea controlar el mensaje por completo, puede escribir un comparador personalizado. O podría usar una afirmación, como esta:

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

¿Puede explicar cuál es su caso de uso? ¿Por qué 10 no es igual a 5 no está a la altura del tabaco, y con qué frecuencia ha tenido esta necesidad?

Este es el tipo de cosas que solicita:

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)

Entonces de esta manera puedes escribir:

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

1
Hay situaciones en las que tuve que poner más de una afirmación en una prueba it () y hay más de una comparación de enteros. Al mirar los registros, no queda claro qué afirmación ha fallado.
Udayakumar Rayala

Pero la forma con withClue de especificarlo no es legible. ¿No hay alguna forma de especificar el mensaje al final?
Udayakumar Rayala

1
Al final, no es factible con el DSL del comparador, pero puede escribir un método que coloque los parámetros de withClue en el orden opuesto. Agregaré un ejemplo a la respuesta.
Bill Venners

12

Nueva forma desde 2011: Matchersy AppendedCluerasgos. Además, para los tamaños de colección, hay algunos mensajes predeterminados.

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

La salida se ve así:

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)

Tenga en cuenta que el Listmensaje de tamaño no es bueno para listas con .toStringsalida larga .

Consulte el scaladoc para obtener más información.


3

También puede usar withCluesin importar nada o agregarlo a la clase de prueba:

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

Esto se importa de la Assertionsclase:org.scalatest.Assertions#withClue

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.