03.2. - JUnit
03.2. - JUnit
JUnit
Objetivos
1 - 152
Introducción
• 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.
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
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.
• 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
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.
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.
class DisplayNameDemo {
@Test
@DisplayName("Custom test name")
void testWithDisplayName() { ... }
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.
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).
@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
1 - 164
Junit. Aserciones
• Cuando definimos un método de prueba, deberemos definir las condiciones de ese método
de prueba.
@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.
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.
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);
:
@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.
• 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.
4. Ejecutar el Test
1. Ejecutar la nueva clase creadas como → JUnit Test.
1 - 172
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)?
1 - 174
Junit. 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
• 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
1 - 177
Junit. Cobertura
1 - 178
Junit. Cobertura
• 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