Afirmar mensajes en pruebas

Hola de nuevo. En previsión del inicio del curso "C # Developer", hemos traducido material interesante sobre mensajes de afirmación en las pruebas y nos complace compartir la traducción con usted.




En esta publicación, hablaremos sobre si debe usar los mensajes de afirmación en sus pruebas.

Recibí una pregunta interesante de un colega lector, que me gustaría analizar con más detalle:

tengo una pregunta sobre los mensajes de Assert: ¿debo usar la sobrecarga que contiene el parámetro del mensaje y usarla para enviar una cadena que describa la razón del fallo de Assert (también "Reclamaciones") ?

La respuesta a esta pregunta se reduce a dos aspectos:

  • Legibilidad de la prueba: cuán fácil es comprender lo que hace la prueba.
  • Facilidad de diagnóstico: cuán fácil es entender por qué falla la prueba.

Discutamos cada uno de ellos individualmente

Legibilidad de prueba


Las personas a menudo usan los mensajes Assert para ayudar a los miembros del equipo y a sí mismos en el futuro a comprender lo que sucede en la prueba. Veamos el siguiente ejemplo:

[Test]
public void Hiring_a_new_team_member()
{
    var company = new Company();
    var person = new Person(UserType.Customer);

    company.HireNewMember(person);

    Assert.AreEqual(UserType.Employee, person.Type); //  
    Assert.AreEqual(1, company.NumberOfEmployees); //  
}

En lugar de un Assert simple, también puede indicar la razón por la cual el Assert de prueba valida algo:

[Test]
public void Hiring_a_new_team_member()
{
    var company = new Company();
    var person = new Person(UserType.Customer);

    company.HireNewMember(person);

    Assert.AreEqual(UserType.Employee, person.Type, "Person must become an employee after hiring");
    Assert.AreEqual(1, company.NumberOfEmployees, "Number of employees must increase");
}

Tales declaraciones ayudan, pero tienen un precio. Estos mensajes te requieren

  • Pasa tiempo escribiéndolos
  • Mantenlos avanzando

Aquí el conjunto de pros y contras es el mismo que en los comentarios al código. Y, como en el caso de los comentarios, le aconsejo: no escriba mensajes de afirmación únicamente con fines de legibilidad. Si cree que la prueba no es obvia sin mensajes de afirmación, intente refactorizarla. A la larga, es más fácil hacer que la prueba hable por sí misma que mantenerla sincronizada con los mensajes de afirmación (y esto es solo cuestión de tiempo antes de que se interrumpa la sincronización).

Ingrese mensajes de confirmación solo cuando sea absolutamente necesario, cuando no pueda mejorar la legibilidad de la prueba de ninguna otra manera. Pero incluso entonces, inclínate a elegir no escribirlos.

La forma más fácil de obtener una ganancia rápida en la legibilidad de una prueba es cambiar a un registro legible de declaraciones. Por ejemplo, NUnit tiene un modelo de declaración especial basado en restricciones que le ayuda a escribir sus declaraciones de la siguiente manera:

[Test]
public void Hiring_a_new_team_member()
{
    var company = new Company();
    var person = new Person(UserType.Customer);

    company.HireNewMember(person);

    Assert.That(person.Type, Is.EqualTo(UserType.Employee));
    Assert.That(company.NumberOfEmployees, Is.EqualTo(1));
}

O puedes usar mis afirmaciones fluidas favoritas :

[Test]
public void Hiring_a_new_team_member()
{
    var company = new Company();
    var person = new Person(UserType.Customer);

    company.HireNewMember(person);

    person.Type.Should().Be(UserType.Employee);
    company.NumberOfEmployees.Should().Be(1);
}

Estas declaraciones se leen en inglés simple, exactamente de la manera en que le gustaría que se leyera todo el código. Los humanos preferimos percibir la información en forma de historias. Todas las historias se adhieren a este modelo:

[] [] [].

Por ejemplo,

  .

Aquí , el sujeto, la acción y el objeto. Lo mismo vale para el código.

Esta versión

company.NumberOfEmployees.Should().Be(1);

lee mejor que

Assert.AreEqual(1, company.NumberOfEmployees);

precisamente porque la historia se rastrea aquí.
, . , .


Otra visión de los mensajes de afirmación es en términos de facilidad de diagnóstico. En otras palabras, la simplicidad de comprender la causa de una falla en la prueba sin examinar el código para esta prueba. Esto es útil al leer los resultados del ensamblaje de CI.

Desde el punto de vista del diagnóstico, siga esta guía: si puede reiniciar fácilmente la prueba localmente, esta prueba no necesita un mensaje de afirmación. Esto es cierto para todas las pruebas unitarias (ya que no funcionan con dependencias fuera de proceso), pero en menor medida para las pruebas de integración y de extremo a extremo.


Pirámide de prueba

A medida que asciende en la pirámide de prueba, es posible que necesite información más detallada, ya que las pruebas de integración (y especialmente de extremo a extremo) son más lentas y es posible que no pueda volver a ejecutarlas a voluntad.

Pero incluso con la integración y las pruebas de extremo a extremo, hay formas de facilitar el diagnóstico sin recurrir a los mensajes de afirmación:

  • Haga que la prueba de prueba sea un módulo de comportamiento: cuando una prueba verifica una cosa, a menudo es fácil determinar qué salió mal. (Esto no siempre es aplicable a las pruebas de extremo a extremo, ya que es posible que desee que estas pruebas verifiquen cómo funcionan varias unidades de comportamiento estrechamente).
  • Asigne un nombre a sus pruebas unitarias en consecuencia : el nombre de prueba ideal describe el comportamiento de la aplicación en términos comerciales para que incluso un no programador pueda entenderla.

Y no olvide que incluso sin las declaraciones del usuario, todavía tiene los mensajes que el entorno de prueba de la unidad genera para usted.

Por ejemplo, un error en la siguiente declaración:

person.Type.Should().Be(UserType.Employee);

da el siguiente mensaje de error:

Xunit.Sdk.EqualException: Assert.Equal() Failure
Expected: Employee
Actual:   Customer

La combinación de tales mensajes generados por el entorno y los nombres de prueba legibles por humanos hace que el 90% de los mensajes de afirmación del usuario sean inútiles incluso en términos de facilidad de diagnóstico. La única excepción son las largas pruebas de extremo a extremo. A menudo contienen comprobaciones en varias etapas, por lo que tiene sentido utilizar mensajes de afirmación adicionales para comprender cuál de los pasos falló. Sin embargo, no debería haber muchas pruebas de extremo a extremo.

Por supuesto, para aprovechar los mensajes de error generados por el marco, debe evitar las comparaciones booleanas comunes, como:

(person.Type == UserType.Employee).Should().BeTrue();

Porque conducen al siguiente mensaje de error:

Xunit.Sdk.TrueException: Assert.True() Failure
Expected: True
Actual:   False

Lo que no ayuda con el diagnóstico en absoluto.

Resumen


¿A menudo te sientes flojo cuando se trata de escribir declaraciones? Bueno, ahora puedes justificarlo y enviar a tus colegas a este artículo.


"Estoy contento de que esto tenga un nombre"

Bromas aparte, sin embargo, aquí hay un resumen:

  • Hay dos aspectos para usar mensajes de afirmación:
    • Legibilidad de la prueba (cuán fácil es entender lo que hace la prueba).
    • Facilidad de diagnóstico (cuán fácil es comprender por qué la prueba falla durante la compilación de CI).
  • En términos de legibilidad de la prueba, los mensajes de afirmación son comentarios de código. En lugar de confiar en ellos, refactorice su prueba para lograr la legibilidad.
  • En términos de facilidad de diagnóstico, la mejor alternativa para hacer valer mensajes es:
    • Probar un solo módulo de comportamiento mediante una prueba
    • Pruebas de nomenclatura en términos comerciales
  • La única excepción son las largas pruebas de extremo a extremo.

Eso es todo. Puede obtener más información sobre nuestro curso en el seminario web gratuito , que se realizará hoy.

All Articles