JUnit

Descargar como pptx, pdf o txt
Descargar como pptx, pdf o txt
Está en la página 1de 31

Tests Unitarios

con JUnit 4

Temario

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

Tipos de Tests

Clasificacin por Nivel

(1/3)

Tests
Tests
Tests
Tests

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

Pruebas Funcionales

Tests Funcionales.
Tests de Aceptacin.
Tests de Regresin (cambios en cdigo funcionan).
Alpha testing.
Beta testing.
...

Tipos de Tests

Pruebas No-funcionales

Tests
Tests
Tests
Tests
Tests
...

de Rendimiento
de Resistencia, Carga, Stress
de Seguridad
de Usabilidad
de Mantenibilidad

(2/3)

Tipos de Tests

(3/3)

Clasificacin tpica en un entorno TDD.


Desarrollador

Tests
Unitarios

Dueo del Producto

Tests de
Aceptacin
Tests
Funcionales

Tests de Sistema
Tests de
Integracin

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

(2/3)

Ventajas:
1. Fomentan el cambio.
2. Simplifica la integracin.
3. Documentan el cdigo.
4. Separacin de la interfaz y la implementacin.
5. Los errores quedan ms acotados y son ms
fciles de localizar.

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 a
y un coste eficiente.

Introduccin a JUnit

(1/3)

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.

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

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

Introduccin a JUnit
JUnit proporciona:

(2/3)

Afirmaciones para verificar resultados.


Anotaciones para definir mtodos de
prueba.
pre y
Anotaciones para definir mtodos
adicionales
post prueba.
espera. de las
Controlar
Diferentesexcepciones,
Runners paratiempos
guiar lade
ejecucin
Parametrizacin
de datos.
pruebas.
...

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

Assert

Fixture method
Test suite
Test runner

(3/3)

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() {
...
}
}

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.

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);
}

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().

assertSame("message", A, B)

Validar que A y B son el mismo objeto,


utiliza el operador ==.

assertTrue("message", A)

Validar que la condicin A es true.

assertNotNull("message", A)

Validar que el objeto A no es nulo.

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 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 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.

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 Runners
JUnit permite definir cmo se han de ejecutar nuestros
tests, mediante el uso de diferentes Tests Runners.
org.junit.runners.JUnit4

Runner por defecto.

org.junit.runners.Parameterized

Ejecuta mltiples veces cada test con


diferentes parmetros.

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.

Utilizamos la anotacin @RunWith


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

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 Parametrizados

(2/2)

AssertThat y Hamcrest

(1/2)

La librera de matchers Hamcrest nos permite escribir


validaciones de forma ms clara y fcil.
@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.

AssertThat y Hamcrest
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
...

(2/2)

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.

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)

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) {
...
}
}

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)

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);
}

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);
}

Caso de ejemplo

(5/5)

Podemos refactorizar la clase de test para evitar


duplicidad de cdigo.

public class CalculadoraImpuestosImplTest {


private CalculadoraImpuestosImpl calculadora;

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

@After
public void finaliza() {
calculadora = null;
}

@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);

También podría gustarte