Tests Unitarios con JUnit 4

35
Tests Unitarios con JUnit 4 Paulo Clavijo Esteban - Mayo 2012 [email protected]

description

Introducción a los tests unitarios utilizando el framework JUnit 4. Mayo 2012.

Transcript of Tests Unitarios con JUnit 4

Page 1: Tests Unitarios con JUnit 4

Tests Unitarioscon JUnit 4Paulo Clavijo Esteban - Mayo [email protected]

Page 2: Tests Unitarios con JUnit 4

Agenda● Tipos de Tests● Introducción a JUnit● Test Class● Test Methods● Condiciones de aceptación Assert● Fixture Methods● Test Suites● Tests de Timeout● Tests de manejo de excepciones● Test Runners● Tests Parametrizados● AssertThat y Hamcrest● Buenas Prácticas● Tipos de validación

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 3: Tests Unitarios con JUnit 4

Tipos de Tests (1/3)

● Clasificación por Nivel○ Tests Unitarios.○ Tests de Integración.○ Tests de Sistema.○ Tests de Integración de Sistemas.

● Pruebas Funcionales

○ Tests Funcionales.○ Tests de Aceptación.○ Tests de Regresión.○ Alpha testing.○ Beta testing.○ ...

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 4: Tests Unitarios con JUnit 4

Tipos de Tests (2/3)

● Pruebas No-funcionales ○ Tests de Rendimiento○ Tests de Resistencia, Carga, Stress○ Tests de Seguridad○ Tests de Usabilidad○ Tests de Mantenibilidad○ ...

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 5: Tests Unitarios con JUnit 4

Tipos de Tests (3/3)

Tests Unitarios

Tests de Sistema

Tests de Integración

● Clasificación típica en un entorno TDD.

Tests de Aceptación

Tests Funcionales

Desarrollador Dueño del Producto

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 6: Tests Unitarios con JUnit 4

Tests Unitarios (1/3)

Los tests unitarios son una forma de probar el correcto funcionamiento de un módulo o una parte del sistema. Con el fin de asegurar el correcto funcionamiento de todos los módulos por separado y evitar así errores futuros en el momento de la integración de todas sus partes. La idea es escribir casos de prueba para cada función no trivial o método en el módulo, de forma que cada caso sea independiente del resto.

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 7: Tests Unitarios con JUnit 4

Tests Unitarios (2/3)

Ventajas:1. Fomentan el cambio.

2. Simplifica la integración.

3. Documentan el código.

4. Separación de la interfaz y la implementación.

5. Los errores quedan más acotados y son más

fáciles de localizar.

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 8: Tests Unitarios con JUnit 4

Tests Unitarios (3/3)

● Un buen test unitario tiene que ser repetible y debe poder ejecutarse de forma automática.

● Las Pruebas Automáticas reducen el riesgo y

ahorran el coste de repetir los test manualmente.

● Los equipos ágiles, las utilizan como ayuda

para responder al cambio de forma rápida y a un coste eficiente.

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 9: Tests Unitarios con JUnit 4

Introducción a JUnit (1/3)

● JUnit es una librería Java que nos ayudará en la realización de nuestros tests automáticos de prueba.

○ C (CUnit)○ C++ (CPPUnit)○ Fortran (fUnit)○ Delphi (DUnit)

○ Javascript (JSUnit)○ Objective-C (OCUnit)○ PHP (PHPUnit)○ ...

● Creado por Erich Gamma y Kent Beck, es uno de los frameworks de tests unitarios conocidos colectivamente como xUnit, originados por SUnit.

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 10: Tests Unitarios con JUnit 4

Introducción a JUnit (2/3)

● JUnit proporciona:○ Afirmaciones para verificar resultados.○ Anotaciones para definir métodos de prueba.○ Anotaciones para definir métodos adicionales pre y

post prueba.○ Controlar excepciones, tiempos de espera.○ Parametrización de datos.○ Diferentes Runners para guiar la ejecución de las

pruebas.○ ...

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 11: Tests Unitarios con JUnit 4

Introducción a JUnit (3/3)

● Los conceptos básicos de JUnit son:○ Test class

○ Test method

● Assert

○ Fixture method

○ Test suite

○ Test runner

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 12: Tests Unitarios con JUnit 4

Test Class

Una Test Class es una clase java que contendrá un conjunto de Test Methods.Por ejemplo, para probar los métodos de una clase Calculadora creamos la clase CalculadoraTest.

import org.junit.Test; public class CalculadoraTest {

@Testpublic void testXXX() {

...}

}

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 13: Tests Unitarios con JUnit 4

Test Methods (1/2)

Los métodos de prueba deben indicarse con la anotación @Test.Tienen que ser públicos, sin parámetros y devolver void. JUnit crea una nueva instancia de la test class antes de invocar a cada @Test method.

import org.junit.Test; public class CalculadoraTest {

@Testpublic void testSuma() {

Calculadora calculadora = new CalculadoraImpl();double res = calculadora.suma(1, 1);assertEquals(2, res, 0);

}}

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 14: Tests Unitarios con JUnit 4

Test Methods (2/2)

Los métodos de test los creamos siguiendo el patrón AAA:1. Arrange (Preparar)2. Act (Actuar)3. Assert (Afirmar)

@Testpublic void testSuma() {

// ArrangeCalculadora calculadora = new CalculadoraImpl();// Actdouble res = calculadora.suma(1, 1);// AssertassertEquals(2, res, 0);

}

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 15: Tests Unitarios con JUnit 4

Condiciones de aceptación Assert

Para realizar validaciones en nuestros métodos de prueba, utilizamos las condiciones de aceptación assertXXX(), que proporciona la clase Assert de JUnit. Ejemplos:

assertEquals("message", A, B) Validar la igualdad de los objetos A y B, utiliza el método equals().

assertSame("message", A, B) Validar que A y B son el mismo objeto, utiliza el operador ==.

assertTrue("message", A) Validar que la condición A es true.

assertNotNull("message", A) Validar que el objeto A no es nulo.

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 16: Tests Unitarios con JUnit 4

Fixture Methods

Las clases de tests tienen que programarse eficientemente y refactorizarse cuando sea necesario.JUnit nos proporciona anotaciones para definir métodos adicionales pre/post test. Mediante los que podemos inicializar o finalizar elementos comunes, evitar duplicidades, preparar datos, etc. @BeforeClass @Before @After @AfterClass

public class CalculadoraTest {Calculadora calculadora;

@Beforepublic void inicializa() {

calculadora = new CalculadoraImpl();}

@Testpublic void testSuma() {

double res = calculadora.suma(1, 1);assertEquals(2, res, 0);

}}

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 17: Tests Unitarios con JUnit 4

Tests de Timeout

Podemos realizar sencillos test de rendimiento verificando que un test no exceda un tiempo límite de ejecución.Para ello utilizamos el parámetro timeout. El test fallará, si se demora más de 100 milisegundos.

@Test(timeout=100)public void testProcessTimeout() {

...}

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 18: Tests Unitarios con JUnit 4

Tests de manejo de excepciones

Si estamos probando un método que puede lanzar excepciones, nos es de interés poder verificar, que para las condiciones oportunas, nuestro código lanza la excepción esperada.Para ello utilizamos el parámetro expected. El test fallará, si no se produce la excepción IllegalArgumentException.

@Test(expected=IllegalArgumentExcepcion.class)public void testSumaGetIllegalArgumentException() {

...}

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 19: Tests Unitarios con JUnit 4

Ignorar un Test

JUnit proporciona una anotación para indicar que un determinado test no queremos que se ejecute. Evitar un test no es una buena práctica, pero si en alguna ocasión nos es necesario es mejor utilizar la anotación @Ignore a simplemente comentar código.Es importante indicar siempre una razon por la que ignoramos un test con el parámetro value.

@Ignore(value="Mensaje")@Testpublic void testXXX() {

...}

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 20: Tests Unitarios con JUnit 4

Tests Runners

JUnit permite definir cómo se han de ejecutar nuestros tests, mediante el uso de diferentes Tests Runners. Utilizamos la anotación @RunWith

@RunWith(value=Parameterized.class) public class CalculadoraImplParameterizedTest {

org.junit.runners.JUnit4 Runner por defecto.

org.junit.runners.Parameterized Ejecuta múltiples veces cada test con diferentes parámetros.

org.junit.runners.Suite Runner de los Test Suite

org.springframework.test.context.junit4.SpringJUnit4ClassRunner

Runner de Spring para que los tests puedan trabajar con el contenedor IoC.

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 21: Tests Unitarios con JUnit 4

Tests Parametrizados (1/2)

Parameterized es un test runner que nos permite ejecutar un test múltiples veces con diferentes juegos de parámetros.

@RunWith(value=Parameterized.class)public class CalculadoraImplParameterizedTest {

private double esperado, num1, num2;

@Parameterspublic static Collection<Integer[]> gestTestParameters(){

return Arrays.asList(new Integer[][] { {2, 1, 1}, {3, 2, 1}, {4, 3 ,1}, });

}

public CalculadoraImplParameterizedTest(double esperado, double num1, double num2) {this.esperado = esperado;this.num1 = num1;this.num2 = num2;

}

@Testpublic void testSuma() {

CalculadoraImpl calculadora = new CalculadoraImpl();double calculado = calculadora.suma(num1, num2);assertEquals(esperado, calculado, 0);

}}

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 22: Tests Unitarios con JUnit 4

Tests Parametrizados (2/2)

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 23: Tests Unitarios con JUnit 4

AssertThat y Hamcrest (1/2)

La librería de matchers Hamcrest nos permite escribir validaciones de forma más clara y fácil. Además, con Hamcrest, los errores en los assert son más descriptivos.

@Testpublic void testSumaHamcrest() {

CalculadoraImpl calculadora = new CalculadoraImpl();double calculado = calculadora.suma(num1, num2);assertThat(esperado, is(calculado));

}

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 24: Tests Unitarios con JUnit 4

AssertThat y Hamcrest (2/2)

Matches Hamcrest mas comunes:● anything● is● allOf● anyOf● not● instanceOf, isCompatibleType● sameInstance● notNullValue, nullValue● hasProperty● hasEntry, hasKey, hasValue● hasItem, hasItems● closeTo, greaterThan, lessThan● containsString, endsWith, startWith● ...

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 25: Tests Unitarios con JUnit 4

Buenas Prácticas

● Un test unitario debe probar exclusivamente el SUT.● Un test unitario no puede modificar el estado del

sistema.● Un test unitario tiene que ser pequeño, debe probar una

sola funcionalidad, para un único objeto cada vez.● Los nombres de los métodos de test deben ser los más

claros posibles. No importa que utilicemos nombres largos.

● Indicar un mensaje en todas las llamadas assert.● Deja que los tests mejoren el código.

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 26: Tests Unitarios con JUnit 4

Tipos de validación

● Recapitulando, observamos que en nuestros tests unitarios realizamos diferentes tipos de comprobaciones:○ Validación de estado

assertEquals ( valorEsperado, valorCalculado )

○ Validación excepciones@Test ( expected=IllegalArgumentException.class )

○ Validación rendimiento@Test ( timeout=100 )

○ Validación interacciónUtilizaremos Dobles (Mocks, Stubs, etc)

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 27: Tests Unitarios con JUnit 4

Caso de ejemplo (1/5)

● Una Calculadora de Impuestos.

public interface CalculadoraImpuestos {

public double calculaImpuestoMatriculacion(double valorVehiculo, int cv);}

public class CalculadoraImpuestosImpl implements CalculadoraImpuestos {

public double calculaImpuestoMatriculacion(double valorVehiculo, int cv) {...

}}

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 28: Tests Unitarios con JUnit 4

Caso de ejemplo (2/5)

● Creamos la clase que contendrá las pruebas.

import static org.junit.Assert.*; import org.junit.Test; public class CalculadoraImpuestosImplTest {

@Testpublic void test() {

fail("Not yet implemented");}

}

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 29: Tests Unitarios con JUnit 4

Caso de ejemplo (3/5)

● 1ª Regla de negocio:Vehículos con menos de 70CV impuesto 9%

● Primer test:@Testpublic void testUsoImpuestoEcologicoParaCvMenor70() { CalculadoraImpuestosImpl calculadora = new CalculadoraImpuestosImpl(); double valorVehiculo = 10000; int cv = 65; double impuestoEsperado = 900; double impuestoCalculado = calculadora.calculaImpuestoMatriculacion(valorVehiculo, cv); assertEquals("Impuesto para vehiculos de menos de 70 CV debería ser del 9%", impuestoEsperado, impuestoCalculado, 0); }

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 30: Tests Unitarios con JUnit 4

Caso de ejemplo (4/5)

● 2ª Regla de negocio:Un vehículo no puede tener 0CV

● Segundo test:

@Test(expected=IllegalArgumentException.class) public void test0CvGetIllegalArgumentException() {

CalculadoraImpuestosImpl calculadora = new CalculadoraImpuestosImpl();calculadora.calculaImpuestoMatriculacion(100.0, 0);

}

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 31: Tests Unitarios con JUnit 4

Caso de ejemplo (5/5)

● Podemos refactorizar la clase de test para evitar duplicidad de código.

public class CalculadoraImpuestosImplTest {private CalculadoraImpuestosImpl calculadora;

@Beforepublic void inicializa() {

calculadora = new CalculadoraImpuestosImpl();}

@Afterpublic void finaliza() {

calculadora = null;}

@Testpublic void testUsoImpuestoEcologicoParaCvMenor70() {

double valorVehiculo = 10000;int cv = 65;double impuestoEsperado = 900;double impuestoCalculado = calculadora.calculaImpuestoMatriculacion(valorVehiculo, cv);assertEquals("Impuesto para vehiculos de menos de 70 CV debería ser del 9%", impuestoEsperado,

impuestoCalculado, 0);}

@Test(expected=IllegalArgumentException.class)public void test0CvGetIllegalArgumentException() {

calculadora.calculaImpuestoMatriculacion(100.0, 0);}

}

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 32: Tests Unitarios con JUnit 4

Temas para otro día ...

● Dobles de Prueba (Mocks, Stubs)● Tests de Integración con JUnit● La extensión DBUnit● TDD - Desarrollo Dirigido por Tests

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 33: Tests Unitarios con JUnit 4

Recursos

● JUnit Framework● Hamcrest● EasyMock● Mockito

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 34: Tests Unitarios con JUnit 4

Referencias

Libros:● JUnit In Action (2º Edition) - Manning.● Java Power Tools - John Ferguson.● Diseño Ágil Con TDD - Carlos Blé. Web:● JUnit Documentacion● The Hamcrest Tutorial

Tests Unitarios con JUnit 4Paulo Clavijo Esteban - Mayo 2012

Page 35: Tests Unitarios con JUnit 4

Sobre el Autor:

Paulo Clavijo EstebanSoftware Engineer en ISC

[email protected]

Blog: www.lintips.com

Email: [email protected]

Sobre el Autor:

Paulo Clavijo EstebanSoftware Engineer en ISC

[email protected]

Blog: www.lintips.com

Email: [email protected]