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
