0% encontró este documento útil (0 votos)
35 vistas29 páginas

03.2. - JUnit

JUnit

Cargado por

crepuscularcorso
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
35 vistas29 páginas

03.2. - JUnit

JUnit

Cargado por

crepuscularcorso
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 29

3.

JUnit
Objetivos

Después de completar este curso, deberías poder:


• Conocer los principios básicos del Testing
• Utilizar Junit para realizar pruebas unitarias

1 - 152
Introducción

• El software generado en la fase de implementación no puede ser "entregado" al cliente para


que lo utilice, sin practicarle antes una serie de pruebas.

• La fase de pruebas tienen como objetivo encontrar defectos en el sistema final debido a la
omisión o mala interpretación de alguna parte del análisis o el diseño.

• Los defectos deberán entonces detectarse y corregirse en esta fase del proyecto.

• En ocasiones los defectos pueden deberse a errores en la implementación de código


(errores propios del lenguaje o sistema de implementación, etc

1 - 153
Introducción

• La prueba puede ser llevada a cabo durante la implementación, para verificar que el
software se comporta como su diseñador pretendía, y después de que la implementación
esté completa.

• Esta fase tardía de prueba comprueba la conformidad con los requerimientos y asegura la
fiabilidad del sistema.

• Hay muchos tipos de pruebas de distintas clases utilizadas para diferentes escenarios:
• La prueba estadística.
• La prueba de defectos.
• La prueba de regresión.
• etc

1 - 154
Introducción

• El desarrollador siempre es responsable de probar las unidades individuales (módulos) del


programa, asegurándose de que cada una lleva a cabo la función para la que fue diseñada.

• En muchos casos, también pueden encargarse de la prueba de integración de todos los


elementos en la estructura total del sistema.

Grupo independiente de prueba


• Sólo una vez que la arquitectura del software esté completa, entra en juego un grupo
independiente de prueba, que debe eliminar los problemas inherentes asociados con el
hecho de permitir al constructor que pruebe lo que ha construido.
• En cualquier caso, el desarrollador y el grupo independiente deben trabajar estrechamente
a lo largo del proyecto de software para asegurar que se realizan pruebas exhaustivas.
• Mientras se dirige la prueba, el desarrollador debe estar disponible para corregir los errores
que se van descubriendo.

1 - 155
Introducción. Principios fundamentales

• Hay 6 principios fundamentales respecto a las metodologías de pruebas que deben quedar
claros desde el primer momento:
1. Las pruebas exhaustivas no son viables
2. Ejecución de pruebas bajo diferentes condiciones
3. El proceso de pruebas no puede demostrar la ausencia de defectos
4. Las pruebas no garantizan ni mejoran la calidad del software
5. Las pruebas tienen un coste
6. Inicio temprano de pruebas

1 - 156
Introducción. Principios fundamentales

• Hay 6 principios fundamentales respecto a las metodologías de pruebas que deben quedar
claros desde el primer momento:
1. Las pruebas exhaustivas no son viables
2. Ejecución de pruebas bajo diferentes condiciones
3. El proceso de pruebas no puede demostrar la ausencia de defectos
4. Las pruebas no garantizan ni mejoran la calidad del software
5. Las pruebas tienen un coste
6. Inicio temprano de pruebas

1 - 157
JUnit

• JUnit es un entorno de pruebas opensource que nos permiten probar nuestras aplicaciones
Java y permite la creación de los componentes de prueba automatiza que implementan uno
o varios casos de prueba.

• JUnit 5 requiere Java 8 (o superior) en tiempo de ejecución.


• Sin embargo, aún puede probar el código que se ha compilado con versiones anteriores del
JDK.

• A diferencia de las versiones anteriores de JUnit, JUnit 5 está compuesto por varios módulos
diferentes de tres subproyectos diferentes:.
• La plataforma JUnit: Sirve como base para lanzar marcos de prueba en la JVM.
• JUnit Jupiter: Es la combinación del nuevo modelo de programación y el modelo de extensión
para escribir pruebas y extensiones en JUnit 5.
• JUnit Vintage: Proporciona una función TestEngine para ejecutar pruebas basadas en JUnit 3
y JUnit 4 en la plataforma.

1 - 158
Junit. Casos de Prueba
• Los casos de prueba son clases que disponen de métodos para probar el comportamiento
de una clase concreta.

• Así, para cada clase que quisiéramos probar definiríamos su correspondiente clase de caso
de prueba.
Clase a probar → Clase de Prueba

• Los casos de prueba se definen utilizando:


• Anotaciones:
• Automatizan el proceso de definición, sondeo y ejecución de las pruebas.
• Aserciones:
• Afirmaciones sobre lo que se esperaba y deben cumplirse para dar la prueba superada.
• Todas las aserciones del método deben cumplirse para superar la prueba.
• La primera aserción que no se cumpla detiene la ejecución del método y marca la prueba como fallida.
• Asunciones:
• Afirmaciones que deben cumplirse para continuar con el método de prueba, en caso de no cumplirse se salta la
ejecución del método y lo marca como tal.

1 - 159
Clases y métodos de prueba

Clase de prueba:
• Cualquier clase, clase static o clase @Nested que contenga al menos un método de prueba,
• Deben tener un solo constructor
• El método de prueba no debe ser abstracto

Método de prueba:
• Cualquier método de instancia anotado con una de las siguientes anotaciones:
@Test, @RepeatedTest, @ParameterizedTest, @TestFactory o @TestTemplate.

Método del ciclo de vida:


• Cualquier método anotado con
@BeforeAll, @AfterAll, @BeforeEach o @AfterEach.

1 - 160
Junit. Documentar las pruebas
• Por defecto, al ejecutar las pruebas, se muestran los nombres de las clases y los métodos
de pruebas.

• Se puede personalizar los nombre mostrados mediante la anotación @DisplayName:


@DisplayName("A special test case")

class DisplayNameDemo {
@Test
@DisplayName("Custom test name")
void testWithDisplayName() { ... }

• También se puede anotar la clase con @DisplayNameGeneration para utilizar un


generador de nombres personalizados transformar los nombres de los métodos a mostrar.
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class Display_Name_Demo {
@Test
void if_it_is_zero() { }

1 - 161
Junit. Ciclo de vida de instancia de prueba

• Para permitir que los métodos de prueba individuales se ejecuten de forma aislada y
evitar efectos secundarios inesperados, JUnit crea una nueva instancia de cada clase de
prueba antes de ejecutar cada método de prueba.

• Este ciclo de vida de instancia de prueba "por método" es el comportamiento


predeterminado en JUnit Jupiter y es análogo a todas las versiones anteriores de JUnit.

• Existen anotaciones @BeforeEach, @AfterEach, @BeforeAll y @AfterAll que


nos permiten tener un comportamiento general y definir el cilco de vida de una instancia de
prueba
Siguiente transparencia

1 - 162
Junit. Ciclo de vida de instancia de prueba

Método Descripción
@BeforeAll public static void • Este método es ejecutado una vez antes de ejecutar todos los test.
method() • Se usa para ejecutar actividades intensivas como conectar a una base de datos.
• Los métodos marcados con esta anotación necesitan ser definidos como static
para trabajar con JUnit.
@BeforeEach public void • Este método es ejecutado antes de cada test.
method() • Se usa para preparar el entorno de test (p.ej., leer datos de entrada, inicializar la
clase).

@AfterEach public void • Este método es ejecutado después de cada test.


method() • Se usa para limpiar el entorno de test (p.ej., borrar datos temporales, restaurar
valores por defecto).

@AfterAll public static void • Este método es ejecutado una vez después que todos los tests hayan
method() terminado.
• Se usa para actividades de limpieza, como por ejemplo, desconectar de la base
de datos.
• Los métodos marcados con esta anotación necesitan ser definidos como static
para trabajar con JUnit.

1 - 163
Junit. Ejecución de pruebas

• Las pruebas se pueden ejecutar desde:


• IDE: IntelliJ IDEA , Eclipse , NetBeans y Visual Studio Code
• Herramientas de compilación: Gradle, Maven y Ant (y en los servidores de
automatización que soporte alguna de ellas)
• Lanzador de consola: aplicación Java de línea de comandos que permite iniciar JUnit
Platform desde la consola.

• Al ejecutarse las pruebas se marcan como:


• Successful: Se ha superado la prueba.
• Failed: Fallo, no se ha superado la prueba.
• Aborted (Skipped): Se ha cancelado la prueba con una asunción.
• Disabled (Skipped): No se ha ejecutado la prueba.
• Error: Excepción en la ejecución del método de prueba, no se ha ejecutado la
prueba.

1 - 164
Junit. Aserciones

• Cuando definimos un método de prueba, deberemos definir las condiciones de ese método
de prueba.

• Estas condiciones son puestas mediantes Aserciones definidas en JUnit

@Test
public void testAssertArrayEquals() {
String[] nombresEsperados = { "java", "junit", "jboss" };
String[] nombresActuales = { "java", "junit", "jboss" };
assertArrayEquals("Fallo - No son los mismos arreglos",
nombresEsperados, nombresActuales);
}

1 - 165
Junit. Aserciones
Disponemos de Aserciones
mas avanzadas utilizando
Aserción Descripción Hamcrest o AssertJ
assertTrue • Sirve para afirmar que un tipo de dato u objeto es verdadero.

assertFalse • Sirve para afirmar que un tipo de dato u objeto es falso.

assertNull • Sirve para afirmar que un tipo de dato u objeto es nulo.

assertThat • Sirve para comparar un tipo de dato u objeto

assertNotNull • Sirve para afirmar que un tipo de dato u objeto no es nulo.

assertNotSame • Sirve para comparar dos tipos de datos y afirmar que son distintos.

assertEquals • Sirve para comparar dos tipos de datos u objetos y afirmar que son iguales.

assertArrayEquals • Sirve para comparar dos arreglos y afirmar distintas propiedades del mismo.

assertThrows • Verifica que se genera una determinada excepción.

assertDoesNotThrow • Verifica que no lanza ninguna excepción.

assertTimeout • Verifica que la ejecución no exceda el timeout dado.

fail • Hace que el método falle.


• Debe ser usado para probar que cierta parte del código no es alcanzable para que el
test devuelva fallo hasta que se implemente el método de prueba.

1 - 166
Junit. Ejemplos de uso de Aserciones
• La aserción siguiente será verdadera • Valores dobles y desviación maxima
@Test @Test
: :
String obj1="Junit"; assertEquals (aDoubleValue,
String obj2="Junit"; anotherDoubleValue, 0.001):
assertEquals(obj1,obj2);
:

• La funcionalidad de «assertSame ()» es • La funcionalidad de «assertNotNull ()»


comprobar que ambos objetos se es verificar que un objeto no sea nulo..
refieren al mismo objeto.

@Test @Test
: :
String string3="test"; String string3="test";
String string4="test"; assertNotNull (string3);
assertSame (string3, string4); :
:

1 - 167
Junit. Ejemplos de uso de Aserciones
@Test
//Variable declaration
String string1="Junit"; String string2="Junit";
String string3="test"; String string4="test";
String string5=null;
int variable1=1; int variable2=2;
int[] airethematicArrary1 = { 1, 2, 3 };
int[] airethematicArrary2 = { 1, 2, 3 };

//Assert statements
assertEquals(string1,string2);
assertSame(string3, string4);
assertNotSame(string1, string3);
assertNotNull(string1);
assertNull(string5);
assertTrue(variable1<variable2);
assertArrayEquals(airethematicArrary1, airethematicArrary2)
:

1 - 168
Junit. Agrupar Aserciones

• La primera aserción que no se cumpla detiene la ejecución del método y marca la prueba
como fallida.

• Si un método de prueba cuenta con varias aserciones, el fallo de una de ellas impedirá la
evaluación de las posteriores por lo que no se sabrá si fallan o no, lo cual puede ser un
inconveniente.

• Para solucionarlo se dispone de assertAll: ejecuta todas las aserciones contenidas e informa
del resultado, en caso de que alguna falle assertAll falla
@Test
void groupedAssertions() {
assertAll("person",
() -> assertEquals("Jane", person.getFirstName()),
() -> assertEquals("Doe", person.getLastName())
);
}

1 - 169
Junit. Pruebas parametrizadas

• Las pruebas parametrizadas permiten ejecutar una prueba varias veces con diferentes
argumentos.

• Se declaran como los métodos @Test normales, pero usan la anotación


@ParameterizedTest y aceptan parámetros.

• Además, se debe declarar al menos una fuente de datos que proporcionará los argumentos
para cada invocación y utilizar los parámetros en el método de prueba
@ValueSource: un array de valores String, int, long, o double
@EnumSource: valores de una enumeración (java.lang.Enum)
@CsvSource: valores separados por coma, en formato CSV (comma-separated values)
@CsvFileSource: valores en formato CSV en un fichero localizado en el classpath
@MethodSource: un método estático de la clase que proporciona un Stream de valores

1 - 170
Junit. Pruebas parametrizadas. @ValueSource

• Es la fuente más simples posibles, permite especificar una única colección de valores
literales y solo puede usarse para proporcionar un único argumento por invocación de
prueba parametrizada.

• Los tipos compatibles son: short, byte, int, long, float, double, char,
boolean, String.
@ParameterizedTest
@ValueSource(ints = { 1, 2, 3 })
void testWithValueSource(int argument) {
assertTrue(argument > 0 && argument < 4);
}

1 - 171
Junit. Etapas de creación de Casos de Pruebas

Para realizar los casos de prueba deberemos realizar las siguientes etapas:
1. Agregar Framework a Eclipse
1. No es necesario actualmente, pues JUnit viene integrado en Eclipse

2. Crear un Test
1. Se crea la clase de Test, pero sin implementación aún y generará un error por defecto.

3. Codificar la Clase Test creada anteriormente


1. Deberemos métodos en esta clase que haga referencia a los métodos de nuestra clase a testear.

4. Ejecutar el Test
1. Ejecutar la nueva clase creadas como → JUnit Test.

5. Comprobar Cobertura (opcional)


1. En una aplicación con mucho código puede ser útil analizar la cobertura y ver si se nos ha
escapado algún test.

1 - 172
Junit.

Ejemplo completo JUNIT

1 - 173
Junit. Cobertura

• Después de solucionar los fallos, nuestra clase parece que se ejecuta de manera
satisfactoria.

• Sin embargo
• ¿podemos asegurar que nuestra clase está definida correctamente?
• Cubren nuestros casos de prueba todas las ramas de ejecución del programa (cobertura)?

• La idoneidad de los test se mide en términos de su cobertura.

• La cobertura de líneas de código determina el porcentaje de líneas de código que son


ejecutadas por los tests.
• El 100% de cobertura no implica la ausencia de errores, pero sí que indica un testeo riguroso.
• Por el contrario, una baja cobertura conlleva a una mayor posibilidad de que el código
contenga errores no detectados.

1 - 174
Junit. Cobertura

• Actualmente existen herramientas en eclipse que permiten medir la cobertura.

• EclEmma es una herramienta para Eclipse que permite visualizar la cobertura del código de
los tests unitarios que hemos realizado.
• Esta herramienta se utiliza cuando estamos realizando pruebas de Caja Blanca, es decir, tenemos el
código fuente que queremos probar disponible.

• EclEmma mide la cobertura de líneas de código, sin embargo, también nos ofrece
información acerca de si una rama de código (p.ej if-the-else) ha sido total o parcialmente
cubierta.

• EclEmma se instala en Eclipse de forma sencilla, desde Help -> Eclipse Marketplace, en el
buscador se pone la palabra EclEmma y se siguen los pasos del instalador del plug-in.

1 - 175
Junit. Cobertura

• Una vez instalado el plugin y reiniciado Eclipse, aparece el siguiente icono en la


barra de herramientas.

• A través de este botón, podemos lanzar los tests de forma que EclEmma analizará qué parte
del código se está cubriendo en ellos.

• Ahora podemos lanzamos las pruebas para el proyecto, situándonos en la raíz del proyecto
y yendo al botón de EclEmma, seleccionamos la opción Coverage as -> JUnit Test, tal y
como aparece en la siguiente figura:

1 - 176
Junit. Cobertura

Vemos cómo las instrucciones


han sido coloreadas, con
verde, aquellas que han sido
cubiertas en las pruebas y con
rojo aquellas que no.

1 - 177
Junit. Cobertura

1 - 178
Junit. Cobertura

• Reglas de coloración del bloque de código fuente:


• El verde es la rama de decisión que está completamente cubierta y totalmente ejecutada.
• El amarillo es una rama de decisión que está parcialmente cubierta y parcialmente ejecutada.
• El rojo es la rama de decisión que no está cubierta y no se ejecuta.

• También puede ver los detalles de cobertura de código de cada archivo de clase desde la
barra de estado de Cobertura

1 - 179

También podría gustarte