¿Debería el mensaje JUnit indicar la condición de éxito o fracaso?


Puedo escribir un mensaje de confirmación de dos maneras. Indicando el éxito:

assertEquals( "objects should be identical", expected, actual );

O indicando la condición de ser roto:

assertEquals( "objects aren't identical", expected, actual );

¿Hay un estándar para esto en JUnit específicamente? Si no, ¿cuáles son los argumentos de cada parte?

P.d. He visto artículos en la web que demuestran ambos sin explicación, por lo que solo decir "buscar en Google" no es una respuesta!

[ACTUALIZACIÓN]

Todo el mundo se está colgando en el hecho de que usé assertEquals y por lo tanto el mensaje es probablemente inútil. Pero, por supuesto, eso es solo porque quería ilustrar la pregunta simplemente.

Así que imagínate que es:

assertTrue( ... big long multi-line expression ... );

Donde un mensaje es útil.

Author: Jason Cohen, 2009-07-02

12 answers

Rara vez me molesto con un mensaje, al menos para assertEquals. Cualquier corredor de prueba sensible explicará que estaba usando assertEquals y las dos cosas que estaban destinadas a ser iguales. Ninguno de tus mensajes da más información que eso.

Normalmente encuentro que los fallos de las pruebas unitarias son cosas transitorias - descubriré rápidamente qué está mal y lo arreglaré. El "averiguar lo que está mal" por lo general implica suficiente detalle que un solo mensaje no va a hacer mucha diferencia. Considere " tiempo ahorrado al tener un mensaje " vs "tiempo dedicado a pensar en mensajes":)

EDITAR: Bien, un caso en el que podría usar un mensaje: cuando hay una descripción compacta en el texto que no es obvia a partir de la representación de cadena del objeto.

Por ejemplo: "Fecha prevista para el 1 de diciembre" al comparar fechas almacenadas en milisegundos.

Sin embargo, no me preocuparía por cómo lo expresas exactamente: solo asegúrate de que sea obvio del mensaje a qué te refieres. Cualquiera " debe ser" o "no fue" está bien-solo "1 de diciembre" no sería obvio.

 30
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-02 15:13:44

De acuerdo con la API de junit, el mensaje es "el mensaje de identificación para el AssertionError", por lo que no es un mensaje que describe la condición que debe cumplirse, sino un mensaje que describe lo que está mal si la condición no se cumple. Así que en tu ejemplo" los objetos no son idénticos " parece ser más conforme.

 20
Author: Reto Gmür,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-15 18:08:39

A diferencia de muchos otros, siento que usar un mensaje es extremadamente útil por muchas razones:

  1. La persona que mira los registros de una prueba fallida puede no ser la persona que escribió la prueba. Puede tomar tiempo leer el código y entender qué caso se pretende abordar con la afirmación. Un mensaje útil ahorrará tiempo.

  2. Incluso en el caso de que sea el desarrollador de la prueba quien esté mirando los registros, pueden haber pasado días o meses desde que se escribió la prueba y, de nuevo, un mensaje puede ahorrar tiempo.

Mi consejo sería escribir el mensaje con una declaración del comportamiento esperado. Por ejemplo:

assertEquals("The method should be invoked 3 times", 3, invocationCount);
 7
Author: Matt Accola,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-28 05:24:55

No creo que importe en absoluto - Ya sabes que ocurrió un fallo, y por lo tanto no importa si el mensaje dice lo que debería haber sucedido, o lo que no debería suceder.

El objetivo del mensaje es ayudarlo cuando puede, no para obtener algo de integridad.

Obviamente, en el caso de assertEquals esto es menos importante, pero el mensaje es importante en el caso de general afirma. El mensaje debería ayudarle a obtener suficiente contexto para entenderlo de inmediato lo que exactamente falló.

Sin embargo, la cantidad de contexto necesario (y por lo tanto los detalles en el mensaje) debe depender de cómo obtenga el informe. Por ejemplo, si lo obtienes en Eclipse, puedes ir e interactuar fácilmente y ver lo que sucedió, por lo que el mensaje es menos importante. Sin embargo, si recibe sus informes por correo electrónico (por ejemplo, desde un servidor de compilación continua), entonces desea que el mensaje proporcione suficiente información para que tenga una idea de lo que está sucediendo antes de ir al código fuente correspondiente.

 3
Author: Uri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-02 15:19:26

Me gustaría responder a la pregunta sin considerar, si un mensaje en general es útil.

Si una prueba falla, algo está mal. Sé esto. Quiero saber por qué está roto. Eso es muy fácil de averiguar porque sólo tengo que abrir el caso de prueba y el SUT. Como dijo Jon, es muy fácil arreglarlo (con suerte; -)).

Pero, ¿qué pasa con el mensaje? El mensaje es para mí un consejo, lo que se podría hacer para convertirlo en un caso de prueba verde. Así que apreciaría si hay un consejos dados en el texto del mensaje, cómo solucionar este problema o dónde buscar el problema.

Otro aspecto interesante sería el uso de expresiones positivas. Vale la pena considerar el uso de mensajes de texto positivos. En tu ejemplo, usaría Objects should be identical. Pero esa es una pequeña razón.

 2
Author: guerda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-03 05:45:20

Veo esta pregunta desde dos perspectivas,

Primero y la perspectiva más común, que ya está siendo discutida por la mayoría de nosotros aquí: Desde la perspectiva de alguien que está viendo los registros y tratando de corregir el error: Creo que ambos mensajes proporcionan la misma información.

La segunda perspectiva es la de alguien que está leyendo / manteniendo / revisando el código: Como hemos estado hablando desde hace siglos sobre la legibilidad y simplicidad del código. Por lo tanto, también es igualmente importante.

Se nos ha hecho creer que mi código debe ser simple y autoexplicativo para que no se necesiten comentarios explícitos y estoy totalmente de acuerdo con él.

Desde esta perspectiva:

Estos mensajes hacen que sea mucho más fácil leer y revisar el código, ya que sirven para el doble propósito de la documentación, así como para informar de errores:

assertEquals( "objects should be identical", expected, actual );
assertTrue( "flag should have been set", flag );
assertNotNull( "object must not be null", object );

Estos mensajes no son tan fáciles de leer, ya que hablan de lo inesperado condición:

assertEquals( "objects aren't identical", expected, actual );
assertTrue( "flag is not set", flag );
assertNotNull( "object is null", object );
 2
Author: Mohd Farid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-20 06:09:14

Vota conmigo también (como Jon), pero la única vez que he usado un mensaje como este (en assert equals) es cuando construyo una sola prueba con una matriz de valores y uno de los elementos de prueba falla: uso el mensaje para indicar qué caso de prueba falló. De lo contrario, el texto es totalmente redundante.

 1
Author: James Hugard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-02 15:22:59

De los javadocs de JUnit:

Afirma que dos objetos son iguales. Si no son un error de afirmación fallida se lanza con el mensaje dado.

De acuerdo con la API, el mensaje puede ser lo que quieras. Yo diría que las dos opciones que usted tiene son las mismas y las dos superfluas. El éxito o el fracaso de la afirmación ya proporciona toda la información que está proporcionando en el mensaje.

Se deduce para mí que usted debe tener cualquiera nada (hay una afirmación que no toma una cadena a propósito) O incluye un mensaje con un significado más allá de lo que ya está allí.

Así que supongo que esta es una reiteración de la respuesta de Jon, pero demasiado detallada para ser un comentario.

 1
Author: Instantsoup,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-02 15:23:32

De acuerdo con las especificaciones, el mensaje es para describir el error cuando ocurre. Y es útil cuando compila su aplicación en un entorno de CI, como Jenkins, y utiliza complementos para analizar los resultados de errores.

Http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertTrue(java.lang.String, boolean)

Parameters:
message - the identifying message for the AssertionError (null okay)
condition - condition to be checked
 1
Author: Wander Costa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-30 13:40:47

No pongo un mensaje para el caso que cite, a menos que esté ejecutando una prueba donde tengo una matriz de valores de prueba similares que estoy ejecutando en un bucle y quiero señalar exactamente cuál falló. Luego agrego un mensaje para decirme cuál.

 0
Author: duffymo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-02 21:04:56

Estoy de acuerdo en que proporcionar un mensaje es útil y siempre proporciono uno.

Para mí, lo útil para incluir es una declaración clara de lo que salió mal - generalmente involucrando las palabras 'debería' o 'no debería'.

Por ejemplo, "los objetos son iguales" es ambiguo - ¿significa que los objetos son iguales y es por eso que la prueba falló? ¿O que los objetos deben ser iguales pero no lo son? Pero si dices "Los objetos deben ser iguales "o" Los objetos no deben ser iguales " es obvio por qué la afirmación fallar.

 0
Author: sync,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-20 21:56:11

Me gusta particularmente cómo el marco de pruebas de Spock fomenta las pruebas que se leen como una historia y han llegado a estructurar las pruebas bajo diferentes marcos de manera similar. No estoy particularmente preocupado por que el mensaje de error individual tenga mucho sentido, mi objetivo es envolver rápidamente mi cabeza alrededor de toda la prueba una vez que la abra:

assertEquals("Cloned and persisted items", mockedTiCount, clonedTis.size());
assertTrue("Belong to new transaction", clonedTis.stream().allMatch(ti -> ti.getTransaction().getId().equals(cloned.getId())));
assertNotEquals("Which has a different ID", t.getId(), cloned.getId());
assertEquals("While the originals are left intact", mockedTiCount, transactionItemRepository.findByTransactionId(t.getId()).size());

Optar por muchas pruebas pequeñas en lugar de algunas grandes ayuda aquí también, al igual que un código de configuración de prueba cuidadosamente estructurado, con suerte reutilizable.

 0
Author: Gregor Petrin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-23 09:28:56