lunes, 6 de noviembre de 2017

Hamcrest: Nivel básico

Siguiendo con el tema del testing, hoy vamos a ver Hamcrest. Es un framework que nos permitirá mejorar nuestras pruebas con JUnit, aumentando la legibilidad de las pruebas. 

Es considerado como un framework de testing de 3 generación. Primera generación es cuando haciamos tests del tipo 'assert(logical statement)'. Segunda generación, cuando haciamos test algo más legibles del tipo 'assertTrue(boolean condition)' en los cuales se indica a través del método que es aquello que se quiere probar. Tercera generación es cuando hacemos aún más legibles esos métodos, del tipo 'assertThat(a, is(b))'. 

Puedes importar distintas librerias de Hamcrest, pero la mas comunes son:
  • Hamcrest-core, la cual contiene el nucleo principal y los métodos más comunes.
  • Hamcrest-library, la cual contiene un conjunto amplio y variado de métodos para pruebas. 
Hamcrest a través del método 'assertThat' de JUnit monta la base para lo que serán sus diferentes pruebas. A continuación vamos a mostrar un ejemplo básico pero teniendo en cuenta que substrayendonos de la complejidad, todos serán similares a este:

import static org.hamcrest.Matchers.equalToIgnoringCase;
import static org.junit.Assert.assertThat;
import org.junit.Test;
public class HamcrestTests {
 String uno = "uno";
 String dos = "dos";
 @Test
 public void equal() {
  assertThat(dos, equalToIgnoringCase(uno));
 }
}

Hamcrest tiene varias ventajas como son:
  • Descripción del error muy intuitiva
java.lang.AssertionError: 
Expected: equalToIgnoringCase("uno")
     but: was dos
 at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
 at org.junit.Assert.assertThat(Assert.java:956)
 at org.junit.Assert.assertThat(Assert.java:923)
 at es.home.example.test.HamcrestTests.equal(HamcrestTests.java:14)
 ...
  • Hacer uso del 'method chaining' con lo cual nos permite encadenar de forma sencilla varias invocaciones.
assertThat(50L, is(both(greaterThan(40L)).and(lessThan(60L))));
  • Permitir el uso de patrones
PatternMatcher dateRange = new PatternMatcher(separatedBy(whitespace(), capture("from", date), "-", capture("to", date)));
String input = "31 Dec 2003 - 16 aug 2008";
Parse parse = dateRange.parse(input);

assertThat(parse.get("from"), equalTo("31 Dec 2003")); 
assertThat(parse.get("to"), equalTo("16 aug 2008")); 
assertThat(parse.get("from.day"), equalTo("31"));
  • Gran cantidad de método ya implementados. Los más comunes son:
    • allOf - busca que coincidan todos los elementos
    • anyOf - busca que al menos uno coincida
    • not - busca que los objetos de la comparación no sean iguales 
    • equalTo ó is - busca que ambos objetos sean iguales
    • hasToString - comprueba que tenga Object.toString
    • instanceOf, isCompatibleType - comprueba el tipo del objeto
    • notNullValue, nullValue - busca que sea nulo
    • sameInstance - compara si son la misma instancia
    • hasEntry, hasKey, hasValue - busca en ojbetos de tipo mapa
    • hasItem, hasItems - busca que una colección tenga determinado elemento
    • hasItemInArray - busca que un array tenga determinado elemento
    • closeTo - busca valores 'float' cercanos
    • greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo - permite busqueda de numeros
    • equalToIgnoringCase ó equalToIgnoringWhiteSpace - permite comparar Strings
    • containsString, endsWith, startsWith - permite comparar partes de una cadena

No hay comentarios:

Publicar un comentario