Teoria Java 7 - Testing
Teoria Java 7 - Testing
👋
Hoy vamos a adentrarnos en el emocionante mundo de las pruebas unitarias en
Java y descubrir una herramienta fundamental: JUnit. Aprenderemos cómo
estructurar nuestras pruebas con JUnit y seguir las convenciones de
nomenclatura adecuadas. Además, exploraremos las aserciones y la estrategia
triple A para escribir pruebas claras y comprensibles.
¡Empecemos! 🚀
Pruebas unitarias
Al utilizar JUnit para realizar pruebas unitarias, es necesario importar las clases y
anotaciones correspondientes. A continuación, te compartimos un ejemplo de
cómo se estructura una clase de prueba en JUnit:
package test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import src.Ejercicio1;
package test;
public class CalculadoraTest {
// pruebas unitarias para Calculadora
}
Esta convención establece una relación clara entre la clase que está siendo
probada y la clase de prueba, lo que facilita la búsqueda de las pruebas
asociadas a una clase específica.
@Test
void testSuma() {
// código de prueba aquí...
}
● should_MethodName_ExpectedBehavior_GivenCondition: Esta
convención es descriptiva y clara. El nombre del método sigue un formato
should-when-given, describiendo el comportamiento esperado dada una
condición específica.
@Test
void should_Suma_ReturnCorrectSum_GivenMultipleNumberPairs() {
// código de prueba aquí...
}
@Test
void suma_GivenMultipleNumberPairs_ReturnsCorrectSum() {
// código de prueba aquí...
}
● given_Precondition_When_StateUnderTest_Then_ExpectedBehavior:
Esta convención de nombres sigue el enfoque Given-When-Then del
desarrollo guiado por el comportamiento. Es muy descriptiva, pero puede
resultar en nombres de métodos largos.
@Test
void
given_MultipleNumberPairs_When_SumaCalled_Then_ReturnsCorrectSum() {
// código de prueba aquí...
}
@Test
void suma_MultipleNumberPairs_CorrectSum() {
// código de prueba aquí...
}
DisplayName
@Test
@DisplayName("Test del método suma() con múltiples pares de números: Debería
retornar la suma correcta")
void testSuma() {
// código de prueba aquí...
}
Aserciones
@Test
void testSuma() {
// La suma debería ser 5
assertEquals(5, 2 + 3);
}
@Test
void testIsEven() {
// 4 debería ser par
assertTrue(4 % 2 == 0);
}
@Test
void testIsOdd() {
// 4 no debería ser impar
assertFalse(4 % 2 != 0);
}
@Test
void testNullValue() {
String str = null;
// La variable debería ser nula
assertNull(str);
}
@Test
void testNotNullValue() {
String str = "Hola mundo";
// La variable no debería ser nula
assertNotNull(str);
}
@Test
void testSameObject() {
String str1 = "Hola mundo";
String str2 = str1;
// Las variables deberían referenciar al mismo objeto
assertSame(str1, str2);
}
@Test
void testNotSameObject() {
String str1 = new String("Hola mundo");
String str2 = new String("Hola mundo");
// Las variables no deberían referenciar al mismo objeto
assertNotSame(str1, str2);
}
@Test
void testArrayEquality() {
int[] array1 = {1, 2, 3};
int[] array2 = {1, 2, 3};
// Los arrays deberían ser iguales
assertArrayEquals(array1, array2);
}
@Test
public void testSquareRoot() {
// El valor de la raíz cuadrada de 4 debería ser 2
assertEquals(2.0, Math.sqrt(4.0));
// La raíz cuadrada de 2 debería ser cercana a 1.4142
assertEquals(1.4142, Math.sqrt(2.0), 0.0001);
}
@Test
void testSuma() {
assertEquals(5, 2 + 3, "La suma debería ser 5");
}
Estrategia triple A
El ciclo de vida de las pruebas unitarias se refiere al proceso y los pasos que
JUnit sigue cuando se ejecutan los tests de una clase. Estos pasos pueden ser
personalizados mediante el uso de anotaciones específicas:
class MyTestClass {
@BeforeAll
static void initAll() {
// Código para configurar el estado antes de todas las pruebas ...
}
}
class MyTestClass {
@BeforeEach
void setUp() {
// Código para configurar antes de cada prueba ...
}
}
class MyTestClass {
@Test
void myTest() {
// Código de la prueba ...
}
}
class MyTestClass {
@AfterEach
void tearDown() {
// Código para limpiar el estado después de cada prueba...
}
}
class MyTestClass {
@AfterAll
static void tearDownAll() {
// Código para limpiar el estado después de todas las pruebas aquí
}
}
Repetición de pruebas
class MyTestClass {
@RepeatedTest(5)
void myRepeatedTest() {
// Código de la prueba aquí...
}
}
class MyTestClass {
@RepeatedTest(5)
void myRepeatedTest(RepetitionInfo repetitionInfo) {
int currentRepetition = repetitionInfo.getCurrentRepetition();
int totalRepetitions = repetitionInfo.getTotalRepetitions();
// Código de la prueba aquí...
}
}
En este caso, “getCurrentRepetition()” nos proporcionará el número de la
repetición actual (1 a 5), y “getTotalRepetitions()” siempre devolverá el número
total de repeticiones (5).
Pruebas parametrizados
class MyTestClass {
@ParameterizedTest
@ValueSource(ints = {2, 3, 5, 7, 11, 13, 17, 19})
public void testEsPrimo(int number) {
assertTrue(Primos.esPrimo(number), "El número debería ser
primo");
}
}
En este caso, la prueba “testEsPrimo” se ejecutará ocho veces, una vez
para cada valor en la lista de enteros proporcionada en @ValueSource.
@ParameterizedTest
@MethodSource("provideStrings")
void testWithExplicitLocalMethodSource(String argument) {
assertNotNull(argument);
}
class CalculadoraTest {
@ParameterizedTest
@CsvSource({"1, 2, 3", "2, 3, 5", "3, 5, 8"})
void testSuma(int num1, int num2, int expectedResult) {
assertEquals(expectedResult, Calculadora.suma(num1, num2), "La
suma debería ser correcta");
}
}
@ParameterizedTest
@CsvFileSource(resources = "/test/day-week-data.csv", numLinesToSkip =
1) // suponiendo que tienes un archivo llamado day-week-data.csv en tu
carpeta de test
void testWithCsvFileSource(String dayWeek, Integer expectedResult) {
Integer result = getNumberDay(dayWeek);
assertEquals(expectedResult, result);
}