Você está na página 1de 35

Tests Unitarios con JUnit 4

Paulo Clavijo Esteban - Mayo 2012


clavijo_pau@ingenieriadesoftware.com

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Agenda
Tipos de Tests Introduccin a JUnit Test Class Test Methods Condiciones de aceptacin Assert Fixture Methods Test Suites Tests de Timeout Tests de manejo de excepciones Test Runners Tests Parametrizados AssertThat y Hamcrest Buenas Prcticas Tipos de validacin

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Tipos de Tests

(1/3)

Clasificacin por Nivel


Tests Unitarios. Tests de Integracin. Tests de Sistema. Tests de Integracin de Sistemas.

Pruebas Funcionales

Tests Funcionales. Tests de Aceptacin. Tests de Regresin. Alpha testing. Beta testing. ...

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

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 4


Paulo Clavijo Esteban - Mayo 2012

Tipos de Tests

(3/3)

Clasificacin tpica en un entorno TDD.


Desarrollador Dueo del Producto

Tests Unitarios

Tests de Aceptacin

Tests Funcionales Tests de Sistema

Tests de Integracin

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Tests Unitarios

(1/3)

Los tests unitarios son una forma de probar el correcto funcionamiento de un mdulo o una parte del sistema. Con el fin de asegurar el correcto funcionamiento de todos los mdulos por separado y evitar as errores futuros en el momento de la integracin de todas sus partes. La idea es escribir casos de prueba para cada funcin no trivial o mtodo en el mdulo, de forma que cada caso sea independiente del resto.

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Tests Unitarios
Ventajas:
1. Fomentan el cambio. 2. Simplifica la integracin. 3. Documentan el cdigo.

(2/3)

4. Separacin de la interfaz y la implementacin. 5. Los errores quedan ms acotados y son ms fciles de localizar.

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Tests Unitarios

(3/3)

Un buen test unitario tiene que ser repetible y debe poder ejecutarse de forma automtica. Las Pruebas Automticas 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 rpida y a un coste eficiente.

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Introduccin a JUnit
JUnit es una librera Java que nos ayudar en la realizacin de nuestros tests automticos de prueba. Creado por Erich Gamma y Kent Beck, es uno de los frameworks de tests unitarios conocidos colectivamente como xUnit, originados por SUnit.

(1/3)

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

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

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Introduccin a JUnit
JUnit proporciona:

(2/3)

Afirmaciones para verificar resultados. Anotaciones para definir mtodos de prueba. Anotaciones para definir mtodos adicionales pre y post prueba. Controlar excepciones, tiempos de espera. Parametrizacin de datos. Diferentes Runners para guiar la ejecucin de las pruebas. ...

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Introduccin a JUnit
Los conceptos bsicos de JUnit son:
Test class Test method

(3/3)

Assert

Fixture method Test suite Test runner

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Test Class
Una Test Class es una clase java que contendr un conjunto de Test Methods. Por ejemplo, para probar los mtodos de una clase Calculadora creamos la clase CalculadoraTest.
import org.junit.Test; public class CalculadoraTest { @Test public void testXXX() { ... } }

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Test Methods

(1/2)

Los mtodos de prueba deben indicarse con la anotacin @Test. Tienen que ser pblicos, sin parmetros y devolver void.
import org.junit.Test; public class CalculadoraTest { @Test public void testSuma() { Calculadora calculadora = new CalculadoraImpl(); double res = calculadora.suma(1, 1); assertEquals(2, res, 0); } }

JUnit crea una nueva instancia de la test class antes de invocar a cada @Test method.

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Test Methods

(2/2)

Los mtodos de test los creamos siguiendo el patrn AAA: 1. Arrange (Preparar) 2. Act (Actuar) 3. Assert (Afirmar)
@Test public void testSuma() { // Arrange Calculadora calculadora = new CalculadoraImpl(); // Act double res = calculadora.suma(1, 1); // Assert assertEquals(2, res, 0); }

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Condiciones de aceptacin Assert


Para realizar validaciones en nuestros mtodos de prueba, utilizamos las condiciones de aceptacin assertXXX(), que proporciona la clase Assert de JUnit. Ejemplos:
assertEquals("message", A, B) Validar la igualdad de los objetos A y B, utiliza el mtodo equals(). Validar que A y B son el mismo objeto, utiliza el operador ==. Validar que la condicin A es true. Validar que el objeto A no es nulo.

assertSame("message", A, B)

assertTrue("message", A) assertNotNull("message", A)

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Fixture Methods
Las clases de tests tienen que programarse eficientemente y refactorizarse cuando sea necesario. JUnit nos proporciona anotaciones para definir mtodos 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; @Before public void inicializa() { calculadora = new CalculadoraImpl(); } @Test public void testSuma() { double res = calculadora.suma(1, 1); assertEquals(2, res, 0); } }

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Tests de Timeout
Podemos realizar sencillos test de rendimiento verificando que un test no exceda un tiempo lmite de ejecucin. Para ello utilizamos el parmetro timeout.

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

El test fallar, si se demora ms de 100 milisegundos.

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Tests de manejo de excepciones


Si estamos probando un mtodo que puede lanzar excepciones, nos es de inters poder verificar, que para las condiciones oportunas, nuestro cdigo lanza la excepcin esperada. Para ello utilizamos el parmetro expected.
@Test(expected=IllegalArgumentExcepcion.class) public void testSumaGetIllegalArgumentException() { ... }

El test fallar, si no se produce la excepcin IllegalArgumentException.

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Ignorar un Test
JUnit proporciona una anotacin para indicar que un determinado test no queremos que se ejecute.
@Ignore(value="Mensaje") @Test public void testXXX() { ... }

Evitar un test no es una buena prctica, pero si en alguna ocasin nos es necesario es mejor utilizar la anotacin @Ignore a simplemente comentar cdigo. Es importante indicar siempre una razon por la que ignoramos un test con el parmetro value.

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Tests Runners
JUnit permite definir cmo se han de ejecutar nuestros tests, mediante el uso de diferentes Tests Runners.
org.junit.runners.JUnit4 org.junit.runners.Parameterized Runner por defecto. Ejecuta mltiples veces cada test con diferentes parmetros. Runner de los Test Suite Runner de Spring para que los tests puedan trabajar con el contenedor IoC.

org.junit.runners.Suite org.springframework.test. context.junit4. SpringJUnit4ClassRunner

Utilizamos la anotacin @RunWith


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

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Tests Parametrizados

(1/2)

Parameterized es un test runner que nos permite ejecutar un test mltiples veces con diferentes juegos de parmetros.
@RunWith(value=Parameterized.class)
public class CalculadoraImplParameterizedTest { private double esperado, num1, num2;

@Parameters public 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; } @Test public void testSuma() { CalculadoraImpl calculadora = new CalculadoraImpl(); double calculado = calculadora.suma(num1, num2); assertEquals(esperado, calculado, 0); } }

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Tests Parametrizados

(2/2)

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

AssertThat y Hamcrest
La librera de matchers Hamcrest nos permite escribir validaciones de forma ms clara y fcil.

(1/2)

@Test public void testSumaHamcrest() { CalculadoraImpl calculadora = new CalculadoraImpl(); double calculado = calculadora.suma( num1, num2); assertThat(esperado, is(calculado)); }

Adems, con Hamcrest, los errores en los assert son ms descriptivos.

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

AssertThat y Hamcrest
Matches Hamcrest mas comunes:

(2/2)

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 4


Paulo Clavijo Esteban - Mayo 2012

Buenas Prcticas
Un test unitario debe probar exclusivamente el SUT. Un test unitario no puede modificar el estado del
sistema. Un test unitario tiene que ser pequeo, debe probar una sola funcionalidad, para un nico objeto cada vez. Los nombres de los mtodos de test deben ser los ms claros posibles. No importa que utilicemos nombres largos. Indicar un mensaje en todas las llamadas assert. Deja que los tests mejoren el cdigo.

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Tipos de validacin
Recapitulando, observamos que en nuestros tests
unitarios realizamos diferentes tipos de comprobaciones: Validacin de estado
assertEquals ( valorEsperado, valorCalculado )

Validacin excepciones
@Test ( expected=IllegalArgumentException.class )

Validacin rendimiento
@Test ( timeout=100 )

Validacin interaccin
Utilizaremos Dobles (Mocks, Stubs, etc)

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Caso de ejemplo
Una Calculadora de Impuestos.

(1/5)

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 4


Paulo Clavijo Esteban - Mayo 2012

Caso de ejemplo
Creamos la clase que contendr las pruebas.
import static org.junit.Assert.*; import org.junit.Test; public class CalculadoraImpuestosImplTest { @Test public void test() { fail("Not yet implemented"); } }

(2/5)

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Caso de ejemplo

(3/5)

1 Regla de negocio: Vehculos con menos de 70CV impuesto 9% Primer test:

@Test public 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 debera ser del 9%", impuestoEsperado, impuestoCalculado, 0); }

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Caso de ejemplo

(4/5)

2 Regla de negocio: Un vehculo 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 4


Paulo Clavijo Esteban - Mayo 2012

Caso de ejemplo

(5/5)

Podemos refactorizar la clase de test para evitar duplicidad de cdigo.


@Before public void inicializa() { calculadora = new CalculadoraImpuestosImpl(); } @After public void finaliza() { calculadora = null; }

public class CalculadoraImpuestosImplTest { private CalculadoraImpuestosImpl calculadora;

@Test public 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 debera ser del 9%" , impuestoEsperado, impuestoCalculado, 0); } @Test(expected=IllegalArgumentException.class) public void test0CvGetIllegalArgumentException() { calculadora.calculaImpuestoMatriculacion(100.0, 0); } }

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Temas para otro da ...


Dobles de Prueba (Mocks, Stubs) Tests de Integracin con JUnit La extensin DBUnit TDD - Desarrollo Dirigido por Tests

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Recursos
JUnit Framework Hamcrest EasyMock Mockito

Tests Unitarios con JUnit 4


Paulo Clavijo Esteban - Mayo 2012

Referencias
Libros:

JUnit In Action (2 Edition) - Manning. Java Power Tools - John Ferguson. Diseo gil Con TDD - Carlos Bl.
Web:

JUnit Documentacion The Hamcrest Tutorial

Sobre el Autor:

Paulo Clavijo Esteban


Software Engineer en ISC
clavijo_pau@ingenieriadesoftware.com Blog: www.lintips.com Email: paucls@gmail.com

Você também pode gostar