Els tests dinàmics són una característica avançada de JUnit 5 que permet crear tests de manera programàtica en temps d'execució. Aquesta funcionalitat és especialment útil quan es necessita generar tests basats en dades o condicions que no es coneixen fins al moment de l'execució.
- Introducció als Tests Dinàmics
Què són els Tests Dinàmics?
Els tests dinàmics són tests que es creen i s'executen en temps d'execució, a diferència dels tests estàtics que es defineixen de manera fixa en el codi. Això permet una major flexibilitat i la capacitat de generar tests basats en dades dinàmiques.
Beneficis dels Tests Dinàmics
- Flexibilitat: Permet crear tests basats en dades o condicions que es determinen en temps d'execució.
- Reutilització: Facilita la reutilització de codi de test per a diferents conjunts de dades.
- Escalabilitat: Pot ajudar a escalar el nombre de tests sense duplicar codi.
- Creant Tests Dinàmics amb JUnit 5
Configuració Inicial
Abans de començar a crear tests dinàmics, assegura't de tenir JUnit 5 configurat en el teu projecte. Aquí tens un exemple de com afegir JUnit 5 al teu projecte Maven:
<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.7.0</version> <scope>test</scope> </dependency>
Exemple Bàsic de Test Dinàmic
A continuació, es mostra un exemple bàsic de com crear un test dinàmic utilitzant JUnit 5:
import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.function.Executable; import java.util.Arrays; import java.util.Collection; import static org.junit.jupiter.api.Assertions.assertTrue; public class DynamicTestsExample { @TestFactory Collection<DynamicTest> dynamicTests() { return Arrays.asList( DynamicTest.dynamicTest("Test 1", () -> assertTrue(isEven(2))), DynamicTest.dynamicTest("Test 2", () -> assertTrue(isEven(4))), DynamicTest.dynamicTest("Test 3", () -> assertTrue(isEven(6))) ); } boolean isEven(int number) { return number % 2 == 0; } }
Explicació del Codi
- @TestFactory: Aquesta anotació s'utilitza per marcar un mètode que genera tests dinàmics.
- DynamicTest.dynamicTest: Aquest mètode estàtic es fa servir per crear instàncies de
DynamicTest
. - Executable: Una interfície funcional que representa el codi del test.
Generant Tests Dinàmics a partir de Dades
Els tests dinàmics són especialment útils quan es vol generar tests a partir d'un conjunt de dades. Aquí tens un exemple de com fer-ho:
import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; import java.util.Arrays; import java.util.Collection; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertTrue; public class DynamicTestsFromData { @TestFactory Stream<DynamicTest> dynamicTestsFromStream() { return Arrays.asList(2, 4, 6, 8, 10).stream() .map(number -> DynamicTest.dynamicTest("Test for number: " + number, () -> assertTrue(isEven(number)))); } boolean isEven(int number) { return number % 2 == 0; } }
Explicació del Codi
- Stream
: Utilitzem un flux ( Stream
) per generar una col·lecció de tests dinàmics. - map: Transformem cada element del flux en un test dinàmic.
- Exercicis Pràctics
Exercici 1: Crear Tests Dinàmics per a Nombres Senars
Crea una classe de tests dinàmics que verifiqui si una sèrie de nombres són senars.
Solució
import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; import java.util.Arrays; import java.util.Collection; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertTrue; public class OddNumberTests { @TestFactory Stream<DynamicTest> dynamicTestsForOddNumbers() { return Arrays.asList(1, 3, 5, 7, 9).stream() .map(number -> DynamicTest.dynamicTest("Test for odd number: " + number, () -> assertTrue(isOdd(number)))); } boolean isOdd(int number) { return number % 2 != 0; } }
Exercici 2: Generar Tests Dinàmics a partir d'una Matriu de Dades
Crea una classe de tests dinàmics que verifiqui si una matriu de parells de nombres compleix una condició específica (per exemple, que la suma dels dos nombres sigui parell).
Solució
import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; import java.util.Arrays; import java.util.Collection; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertTrue; public class PairSumTests { @TestFactory Stream<DynamicTest> dynamicTestsForPairSums() { int[][] data = { {1, 3}, {2, 4}, {5, 5}, {6, 8} }; return Arrays.stream(data) .map(pair -> DynamicTest.dynamicTest("Test for pair: " + Arrays.toString(pair), () -> assertTrue(isSumEven(pair)))); } boolean isSumEven(int[] pair) { return (pair[0] + pair[1]) % 2 == 0; } }
- Conclusió
Els tests dinàmics a JUnit 5 ofereixen una manera poderosa i flexible de crear tests en temps d'execució. Aquesta funcionalitat és especialment útil quan es treballa amb dades dinàmiques o quan es necessita generar un gran nombre de tests de manera programàtica. Amb els exemples i exercicis proporcionats, hauríeu de tenir una bona comprensió de com utilitzar els tests dinàmics en els vostres projectes.
Resum
- Els tests dinàmics permeten crear tests en temps d'execució.
- S'utilitza l'anotació
@TestFactory
per marcar mètodes que generen tests dinàmics. - Els tests dinàmics es poden generar a partir de col·leccions o fluxos de dades.
- Aquesta funcionalitat és útil per a la creació de tests basats en dades dinàmiques i per a la reutilització de codi de test.
Amb aquesta base, esteu preparats per explorar i implementar tests dinàmics en els vostres projectes de JUnit.
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