En aquest tema, explorarem com crear tests parametritzats personalitzats a JUnit. Els tests parametritzats permeten executar el mateix test amb diferents dades d'entrada, la qual cosa és molt útil per verificar el comportament del codi amb diverses condicions.
Objectius
- Entendre la necessitat de tests parametritzats personalitzats.
- Aprendre a crear i configurar tests parametritzats personalitzats.
- Veure exemples pràctics de tests parametritzats personalitzats.
- Introducció als Tests Parametritzats Personalitzats
Els tests parametritzats personalitzats permeten definir com es generen i es passen les dades d'entrada als tests. Això és útil quan les dades d'entrada no es poden definir fàcilment amb les anotacions estàndard de JUnit.
Per què utilitzar tests parametritzats personalitzats?
- Flexibilitat: Permeten definir la lògica de generació de dades d'entrada.
- Reutilització: Poden reutilitzar-se en diferents tests.
- Complexitat: Són útils quan les dades d'entrada són complexes o depenen de condicions específiques.
- Creant un Test Parametritzat Personalitzat
Pas 1: Definir la Classe de Test
Primer, definim la classe de test i utilitzem l'anotació @ParameterizedTest
per indicar que es tracta d'un test parametritzat.
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import java.util.stream.Stream; public class CustomParameterizedTest { @ParameterizedTest @MethodSource("provideTestArguments") void testWithCustomParameters(int input, int expected) { // Implementació del test assertEquals(expected, someMethod(input)); } // Mètode que proporciona els arguments static Stream<Arguments> provideTestArguments() { return Stream.of( Arguments.of(1, 2), Arguments.of(2, 4), Arguments.of(3, 6) ); } // Mètode a testejar int someMethod(int input) { return input * 2; } }
Pas 2: Proveir Arguments Personalitzats
El mètode provideTestArguments
retorna un Stream
d'arguments que es passaran al test. Cada Arguments.of
conté un conjunt de paràmetres que es passaran al mètode de test.
Explicació del Codi
- @ParameterizedTest: Indica que el mètode és un test parametritzat.
- @MethodSource: Especifica el mètode que proporciona els arguments.
- provideTestArguments: Retorna un
Stream
d'arguments. - someMethod: Mètode que es testeja.
- Exemples Pràctics
Exemple 1: Test de Càlcul de Factorial
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import java.util.stream.Stream; public class FactorialTest { @ParameterizedTest @MethodSource("factorialArguments") void testFactorial(int input, int expected) { assertEquals(expected, factorial(input)); } static Stream<Arguments> factorialArguments() { return Stream.of( Arguments.of(0, 1), Arguments.of(1, 1), Arguments.of(2, 2), Arguments.of(3, 6), Arguments.of(4, 24) ); } int factorial(int n) { if (n == 0) return 1; return n * factorial(n - 1); } }
Exemple 2: Test de Validació d'Emails
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import java.util.stream.Stream; public class EmailValidationTest { @ParameterizedTest @MethodSource("emailArguments") void testEmailValidation(String email, boolean isValid) { assertEquals(isValid, isValidEmail(email)); } static Stream<Arguments> emailArguments() { return Stream.of( Arguments.of("[email protected]", true), Arguments.of("invalid-email", false), Arguments.of("[email protected]", true), Arguments.of("bad@domain", false) ); } boolean isValidEmail(String email) { return email.contains("@") && email.contains("."); } }
- Exercicis Pràctics
Exercici 1: Test de Conversió de Temperatura
Crea un test parametritzat per verificar la conversió de graus Celsius a Fahrenheit.
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import java.util.stream.Stream; public class TemperatureConversionTest { @ParameterizedTest @MethodSource("temperatureArguments") void testCelsiusToFahrenheit(double celsius, double expectedFahrenheit) { assertEquals(expectedFahrenheit, celsiusToFahrenheit(celsius), 0.01); } static Stream<Arguments> temperatureArguments() { return Stream.of( Arguments.of(0, 32), Arguments.of(100, 212), Arguments.of(-40, -40), Arguments.of(37, 98.6) ); } double celsiusToFahrenheit(double celsius) { return (celsius * 9/5) + 32; } }
Exercici 2: Test de Càlcul de l'Àrea d'un Cercle
Crea un test parametritzat per verificar el càlcul de l'àrea d'un cercle donat el radi.
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import java.util.stream.Stream; public class CircleAreaTest { @ParameterizedTest @MethodSource("circleAreaArguments") void testCircleArea(double radius, double expectedArea) { assertEquals(expectedArea, calculateArea(radius), 0.01); } static Stream<Arguments> circleAreaArguments() { return Stream.of( Arguments.of(1, Math.PI), Arguments.of(2, 4 * Math.PI), Arguments.of(3, 9 * Math.PI) ); } double calculateArea(double radius) { return Math.PI * radius * radius; } }
Conclusió
Els tests parametritzats personalitzats a JUnit permeten una gran flexibilitat a l'hora de definir i executar tests amb diferents conjunts de dades. Hem vist com crear i configurar aquests tests, així com alguns exemples pràctics per il·lustrar el seu ús. Practicar amb aquests exemples i exercicis t'ajudarà a dominar aquesta tècnica i a millorar la qualitat dels teus tests.
En el següent mòdul, explorarem les suites de test, que ens permetran agrupar i executar múltiples tests de manera organitzada.
Curs de JUnit
Mòdul 1: Introducció a JUnit
Mòdul 2: Anotacions Bàsiques de JUnit
- Entenent @Test
- Utilitzant @Before i @After
- Utilitzant @BeforeClass i @AfterClass
- Ignorant Tests amb @Ignore
Mòdul 3: Assertions a JUnit
Mòdul 4: Tests Parametritzats
- Introducció als Tests Parametritzats
- Creant Tests Parametritzats
- Utilitzant @ParameterizedTest
- Tests Parametritzats Personalitzats
Mòdul 5: Suites de Test
Mòdul 6: Mocking amb JUnit
Mòdul 7: Funcions Avançades de JUnit
Mòdul 8: Millors Pràctiques i Consells
- Escrivint Tests Efectius
- Organitzant el Codi de Test
- Desenvolupament Guiat per Tests (TDD)
- Integració Contínua amb JUnit