En aquest tema, aprendrem com gestionar els timeouts en els tests de JUnit. Els timeouts són útils per assegurar-nos que els nostres tests no es queden bloquejats o triguen massa temps a executar-se. Això és especialment important en entorns de desenvolupament continu on la velocitat i l'eficiència són crucials.
Conceptes Clau
- Timeouts en JUnit: Permeten especificar un límit de temps per a l'execució d'un test.
- Anotació @Test(timeout): Utilitzada per definir el temps màxim d'execució d'un test.
- Timeouts a nivell de mètode: Especificació de timeouts per a mètodes individuals.
- Timeouts a nivell de classe: Especificació de timeouts per a tots els tests d'una classe.
Utilitzant @Test(timeout)
L'anotació @Test(timeout)
s'utilitza per definir un límit de temps en mil·lisegons per a l'execució d'un test. Si el test no es completa dins del temps especificat, es considera fallit.
Exemple Pràctic
import org.junit.Test; public class TimeoutTest { @Test(timeout = 1000) // 1 segon public void testWithTimeout() throws InterruptedException { // Simulant una operació que triga 500ms Thread.sleep(500); } @Test(timeout = 1000) // 1 segon public void testWithTimeoutExceeded() throws InterruptedException { // Simulant una operació que triga 1500ms Thread.sleep(1500); } }
Explicació del Codi
- testWithTimeout: Aquest test es completa dins del límit de temps especificat (1 segon), per tant, passarà.
- testWithTimeoutExceeded: Aquest test excedeix el límit de temps especificat (1 segon), per tant, fallarà.
Timeouts a Nivell de Classe
És possible definir un timeout per a tots els tests d'una classe utilitzant l'anotació @Timeout
a nivell de classe. Aquesta funcionalitat està disponible a JUnit 5.
Exemple Pràctic
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import java.util.concurrent.TimeUnit; @Timeout(value = 1, unit = TimeUnit.SECONDS) // 1 segon per a tots els tests public class TimeoutClassTest { @Test public void test1() throws InterruptedException { // Simulant una operació que triga 500ms Thread.sleep(500); } @Test public void test2() throws InterruptedException { // Simulant una operació que triga 1500ms Thread.sleep(1500); } }
Explicació del Codi
- @Timeout(value = 1, unit = TimeUnit.SECONDS): Defineix un timeout de 1 segon per a tots els tests de la classe.
- test1: Aquest test es completa dins del límit de temps especificat (1 segon), per tant, passarà.
- test2: Aquest test excedeix el límit de temps especificat (1 segon), per tant, fallarà.
Exercicis Pràctics
Exercici 1
Crea un test que simuli una operació que triga 2 segons i defineix un timeout de 3 segons. Verifica que el test passa correctament.
Solució
import org.junit.Test; public class Exercise1Test { @Test(timeout = 3000) // 3 segons public void testWithTimeout() throws InterruptedException { // Simulant una operació que triga 2 segons Thread.sleep(2000); } }
Exercici 2
Crea un test que simuli una operació que triga 4 segons i defineix un timeout de 2 segons. Verifica que el test falla.
Solució
import org.junit.Test; public class Exercise2Test { @Test(timeout = 2000) // 2 segons public void testWithTimeoutExceeded() throws InterruptedException { // Simulant una operació que triga 4 segons Thread.sleep(4000); } }
Errors Comuns i Consells
- No especificar el timeout correctament: Assegura't de definir el timeout en mil·lisegons quan utilitzis
@Test(timeout)
. - Operacions que poden variar en temps: Si una operació pot variar en temps d'execució, considera utilitzar un marge de seguretat en el timeout.
- Tests que depenen de recursos externs: Els tests que depenen de recursos externs (com xarxes o bases de dades) poden necessitar timeouts més amplis.
Conclusió
Els timeouts són una eina poderosa per assegurar que els teus tests no es queden bloquejats i s'executen dins d'un temps raonable. Utilitzant l'anotació @Test(timeout)
o @Timeout
a nivell de classe, pots definir límits de temps per als teus tests i millorar l'eficiència del teu procés de desenvolupament.
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