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

  1. Timeouts en JUnit: Permeten especificar un límit de temps per a l'execució d'un test.
  2. Anotació @Test(timeout): Utilitzada per definir el temps màxim d'execució d'un test.
  3. Timeouts a nivell de mètode: Especificació de timeouts per a mètodes individuals.
  4. 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.

© Copyright 2024. Tots els drets reservats