Pruebas de unidad: aserciones diferidas con Linq

18

¿Está bien agregar aserciones diferidas como esta?

var actualKittens = actualKittens.Select(kitten => {
    Assert.IsСute(kitten);
    return kitten
});

¿Por qué? Así que puedo iterar solo una vez, incluso con sentencias que esperan una colección materializada, por ejemplo:

CollectionAssert.AreEquivalent(expectedKittens, actualKittens.ToList());

Y también podría ser no solo la selección, sino un método con un iterador definido y con muchas comprobaciones y lógica (por ejemplo, algunos conteos y filtros).

La semilla de la duda es la complejidad de leer y depurar dicho código en caso de que la prueba falle.

    
pregunta SerG 02.07.2017 - 19:29

1 respuesta

37
  

¿Está bien agregar aserciones diferidas como esta [..]

No , no lo es. ¿Por qué? Porque si por alguna razón elimina la segunda afirmación, la prueba aún se volverá verde y usted pensaría que todavía funciona pero no funciona, ya que la colección no se enumera. Si tiene dos o más afirmaciones independientes, seguirán haciendo su trabajo incluso si deshabilita una de ellas.

Considera esta combinación:

Assert.IsTrue(actualKittens.All(x => x.IsCute());
CollectionAssert.AreEquivalent(expectedKittens, actualKittens.ToList());

Ahora, incluso si deshabilita o elimina una de las afirmaciones, la otra todavía haría su trabajo. Además, si olvida para materializar la colección, puede tardar más en ejecutarse, pero seguirá funcionando. Las pruebas independientes son más robustas y confiables.

También hay un segundo no . No estoy seguro de cómo lo manejan otros marcos, pero si está utilizando la plataforma MS Test, no sabría qué prueba falló. Si hace doble clic en la prueba fallida, le mostrará el CollectionAssert como fallido, pero en realidad fue el Assert anidado el que salió mal y será extremadamente difícil de depurar. Aquí hay un ejemplo:

    [TestMethod]
    public void TestMethod()
    {
        var numbers = new[] { 1, 2, 3 }.Select(x =>
        {
            Assert.Fail("Wrong number.");
            return x;
        });

        // This will fail and you won't be sure why.
        CollectionAssert.AreEqual(new[] { 1, 2, 3 }, numbers.ToList()); 

    }

Esto significa que la primera prueba es en realidad inútil porque no ayuda a encontrar un error. No sabe si falló porque un número no era válido o porque ambas colecciones eran diferentes.

  

¿Por qué? Así que puedo iterar solo una vez, incluso con sentencias que esperan una colección materializada

Me pregunto por qué te importa? Estas son pruebas unitarias. No tiene que optimizar cada bit de ellos y, por lo general, las pruebas no requieren millones de elementos, por lo que el rendimiento no debería ser una preocupación.

Necesitará mantener dichas pruebas, ¿por qué debería hacerlas más complejas de lo necesario? Escribir simple afirma que el trabajo.

    
respondido por el t3chb0t 02.07.2017 - 19:57

Lea otras preguntas en las etiquetas