En la entrada anterior, Munit I: declaración de test, realizaré una descripción de cómo se definen test; en la presenta entrada, Munit II: aserciones, realizaré una descripción de cómo utilizar las aserciones en los test.
Las aserciones son aquellas comprobaciones lógicas que determinan si el resultado del test es correcto. Las aserciones se definen, entre otras, con las siguientes funciones : assert, assertNotEquals, assertEquals,… Las aserciones están compuestas por una comprobación lógica, o bien, por una comprobación lógica y un mensaje informativo. Unos ejemplos básicos de test son los siguientes:
class AssertEjem1 extends munit.FunSuite { test("Basic assert() 1") { val obtained = 42 val expected = 43 assert(obtained < expected) } test("Basic assert() 2") { val obtained = 42 val expected = 43 assert(obtained < expected, "obtained was smaller than expected") } [...] }
MUnit ofrece la posibilidad de mostrar información sobre aquellos test cuyo resultado no es válido. Para mostrar información adicional, es necesario utilizar la función clue; para su mayor comprehensión, mostramos los siguientes ejemplos de test con sus respectivas salidas por consola:
- Test sin función clue.
class AssertEjem1 extends munit.FunSuite { test("Basic assert() 1") { val obtained = 42 val expected = 43 assert(obtained == expected) } }
La salida por consola es la que se muestra en la siguiente imagen:
- Test con función clue.
class AssertEjem1 extends munit.FunSuite { test("Basic assert() clue - error") { val obtained = 42 val expected = 43 assert(clue(obtained) == clue(expected)) } }
La salida por consola es la que se muestra en la siguiente imagen:
Realizando la comparativa de la información que se muestra en los resultados de los test, al utilizar la función clue, MUnit muestra los datos que se emplean para poder realizar un análisis de los datos que se han tratado en el test y, así, poder realizar las correcciones oportunas en el momento de la definición del test.
La función clue no se usa exclusivamente con valores básicos, podemos utilizar con datos más estructurados como se muestra a continuación:
- Clue con case class.
Supongamos que definimos un test que realiza la comparación entre dos objetos definidos en una case class, el test sería el siguiente:
test("Basic assertEquals() case class".flaky) { case class Library(name: String, awesome: Boolean, versions: Range = 0.to(1)) val munitLibrary = Library("MUnit", true) val mdocLibrary = Library("MDoc", true) assertEquals(clue(munitLibrary), clue(mdocLibrary)) }
La salida por consola es la que se muestra en la siguiente imagen:
Como se observa en la imagen anterior, MUnit muestra la diferencia en los valores de los objetos que se utilizan en la aserción.
- Clue con Map.
Supongamos que queremos definir una aserción de igualdad con dos elementos de tipo Map cuyos valores son diferentes. La definición del test es el siguiente:
test("Basic assertEquals Map".flaky) { assertEquals( clue(Map(1 -> List(1.to(3)))), clue(Map(1 -> List(1.to(4)))) ) }
El resultado no es satisfactorio al no ser iguales los objetos Map y, el resultado del test, muestra las diferencias entre los dos objetos. La salida se muestra en la siguiente imagen:
- Clue con String.
Supongamos que tenemos dos string y queremos verificar que no existen diferencias entre ellos; pero, los strings tienen una longitud grande. La definición del test es el siguiente:
test("Basic assertNoDiff") { val obtainedString = "val x = 41\nval y = 43\nval z = 43" val expectedString = "val x = 41\nval y = 42\nval z = 43" assertNoDiff(obtainedString, expectedString) }
El resultado no es satisfactorio al existir diferencias. La salida se muestra en la siguiente imagen:
- Interceptación de una excepción.
Para capturar una excepción en un test, se utiliza la función intercept. Un ejemplo de uso en un test se muestra en el siguiente código de ejemplo:
test("Basic intercept") { intercept[java.lang.IllegalArgumentException] { def throwException(): Unit = throw new IllegalArgumentException() throwException() } }
- Interceptación de un mensaje de una excepción.
Para capturar un mensaje de una excepción en un test, se utiliza la función interceptMessage. Un ejemplo de uso en un test se muestra en el siguiente código de ejemplo:
test("Basic interceptMessage") { interceptMessage[java.lang.IllegalArgumentException]("My Message Exception") { def throwException(): Unit = throw new IllegalArgumentException("My Message Exception") throwException() } }
MUnit permite definir test para verificar que un snippet de código no tenga errores de compilación. Un ejemplo de uso de este tipo de test cuyo resultado es correcto es el siguiente código:
test("Basic compileError") { compileErrors("val x: String = 2") }
La verificación del resultado de los test es muy intuitiva ya que el concepto de aserciones es utilizado por muchas soluciones; de la misma manera, la captura de excepciones o mensajes. Esta situación supone que la curva de aprendizaje de MUnit no sea grande.
En la siguiente entrada, MUnit III: accesorios, describiré cómo trabajar con los entornos de ejecución.