Salta el contingut
 

Exemple: Proves unitàries parametritzades

Joan Puigcerver Ibáñez

j.puigcerveribanez@edu.gva.es

Llicència: CC BY-NC-SA 4.0

(Reconeixement - NoComercial - CompartirIgual) 🅭

Proves unitàries parametritzades

En aquest exemple veurem com podem fer ús de les proves parametritzades per tal de simplificar el codi i evitar repetir codi innecessàriament.

Proves parametritzades de mètodes estàtics

A l' Exemple: Proves unitàries de pedra, paper i tisores hem vist com fer proves unitàries per al joc de pedra, paper i tisores, on s'han creat una sèrie de proves per comprovar que el joc funciona correctament per a tots els casos possibles.

Podeu observar que l'estructura de les proves és pràcticament la mateixa per a totes les proves, canviant únicament els valors de les variables.

DebugRockPaperScissorsTest.java
package ud4.examples;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class DebugRockPaperScissorsTest {

    @Nested
    class Empat {

        @Test
        @DisplayName("Empat: Pedra vs Pedra")
        void testEmpatPedraPedra() {
            int expected = 0;
            int actual = DebugRockPaperScissors.guanya("pedra", "pedra");

            assertEquals(expected, actual);
        }

        @Test
        @DisplayName("Empat: Paper vs Paper")
        void testEmpatPaperPaper() {
            int expected = 0;
            int actual = DebugRockPaperScissors.guanya("paper", "paper");

            assertEquals(expected, actual);
        }

        @Test
        @DisplayName("Empat: Tisores vs Tisora")
        void testEmpatTisoresTisora() {
            int expected = 0;
            int actual = DebugRockPaperScissors.guanya("tisores", "tisores");

            assertEquals(expected, actual);
        }
    }

    @Nested
    class Jugador1 {

        @Test
        @DisplayName("Jugador 1 guanya: Pedra vs Tisores")
        void testJugador1GuanyaPedraTisores() {
            int expected = 1;
            int actual = DebugRockPaperScissors.guanya("pedra", "tisores");

            assertEquals(expected, actual);
        }

        @Test
        @DisplayName("Jugador 1 guanya: Paper vs Pedra")
        void testJugador1GuanyaPaperPedra() {
            int expected = 1;
            int actual = DebugRockPaperScissors.guanya("paper", "pedra");

            assertEquals(expected, actual);
        }

        @Test
        @DisplayName("Jugador 1 guanya: Tisores vs Paper")
        void testJugador1GuanyaTisoresPaper() {
            int expected = 1;
            int actual = DebugRockPaperScissors.guanya("tisores", "paper");

            assertEquals(expected, actual);
        }
    }

    @Nested
    class Jugador2 {

        @Test
        @DisplayName("Jugador 2 guanya: Tisores vs Pedra")
        void testJugador2GuanyaTisoresPedra() {
            int expected = 2;
            int actual = DebugRockPaperScissors.guanya("tisores", "pedra");

            assertEquals(expected, actual);
        }

        @Test
        @DisplayName("Jugador 2 guanya: Pedra vs Paper")
        void testJugador2GuanyaPedraPaper() {
            int expected = 2;
            int actual = DebugRockPaperScissors.guanya("pedra", "paper");

            assertEquals(expected, actual);
        }

        @Test
        @DisplayName("Jugador 2 guanya: Paper vs Tisores")
        void testJugador2GuanyaPaperTisores() {
            int expected = 2;
            int actual = DebugRockPaperScissors.guanya("paper", "tisores");

            assertEquals(expected, actual);
        }
    }
}

Vegem com podem simplificar la codificació de les proves unitàries amb proves parametritzades.

DebugRockPaperScissorsParametizedTest.java
package ud4.examples;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

import static org.junit.jupiter.api.Assertions.assertEquals;

class DebugRockPaperScissorsParametizedTest {
    @ParameterizedTest(name="\"{0}\" vs \"{1}\" should be {2}")
    @DisplayName("RockPaperScissors::guanya(j1, j2)")
    @CsvSource({
            "pedra,pedra,0",
            "pedra,paper,2",
            "pedra,tisores,1",
            "paper,pedra,1",
            "paper,paper,0",
            "paper,tisores,2",
            "tisores,pedra,2",
            "tisores,paper,1",
            "tisores,tisores,0",
    })
    void testGuanya(String j1, String j2, int expected) {
        int actual = DebugRockPaperScissors.guanya(j1, j2);

        assertEquals(expected, actual);
    }
}

Proves parametritzades d'objectes

A l' Exemple: Proves unitàries d'un cotxe hem vist com fer proves unitàries per a la classe Car, on s'han creat una sèrie de proves per comprovar que la classe funciona correctament en diferents escenaris.

CarTest.java
package ud4.examples.objects;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;

class CarTest {
    public static final String PLATE = "0000 BBB";

    @Nested
    @DisplayName("Constructor tests")
    class Constructor {
        @Test
        @DisplayName("Crea un cotxe amb matrícula")
        void testPlate() {
            Car car = new Car(PLATE);

            assertAll(
                () -> assertEquals(PLATE, car.getPlate()),
                () -> assertEquals(0, car.getKilometers())
            );
        }

        @Test
        @DisplayName("Crea un cotxe amb matrícula i quilòmetres")
        void testPlateAndKilometers() {
            Car car = new Car(PLATE, 100);

            assertAll(
                () -> assertEquals(PLATE, car.getPlate()),
                () -> assertEquals(100, car.getKilometers())
            );
        }
    }

    @Nested
    @DisplayName("Car::accelerate(int speed) tests")
    class AccelerateWithSpeed {
        private Car car;

        @BeforeEach
        void setup() {
            car = new Car(PLATE);
        }

        @Test
        @DisplayName("Car::accelerate(1) increments speed by 1")
        void singleAccelerate() {
            int expected = 1;

            car.accelerate(1);
            int actual = car.getSpeed();

            assertEquals(expected, actual);
        }

        @Test
        @DisplayName("Car::accelerate(5) increments speed by 5")
        void multipleAccelerate() {
            int expected = 5;

            car.accelerate(5);
            int actual = car.getSpeed();

            assertEquals(expected, actual);
        }

        @Test
        @DisplayName("Car::accelerate() multiples times increments speed")
        void multipleAccelerateCalls() {
            int expected = 3;

            car.accelerate(1);
            car.accelerate(2);
            int actual = car.getSpeed();

            assertEquals(expected, actual);
        }
    }

    @Nested
    @DisplayName("Car::accelerate() tests")
    class AccelerateWithoutSpeed {
        private Car car;

        @BeforeEach
        void setup() {
            car = new Car(PLATE);
        }

        @Test
        @DisplayName("Car::accelerate() increments speed by 5")
        void accelerate() {
            int expected = 5;

            car.accelerate();
            int actual = car.getSpeed();

            assertEquals(expected, actual);
        }

        @Test
        @DisplayName("Car::accelerate() multiples times increments speed")
        void multipleAccelerateCalls() {
            int expected = 15;

            car.accelerate();
            car.accelerate();
            car.accelerate();
            int actual = car.getSpeed();

            assertEquals(expected, actual);
        }
    }
}

En aquest cas, podríem parametritzar les proves del mètode Car::accelerate().

@DisplayName("Car::accelerate()")
@ParameterizedTest(name = "{0}x accelerate() should result in speed {1}")
@CsvSource({
    "0, 0",
    "1, 5",
    "3, 15",
})
void accelerateTest(int times, int expectedSpeed) {
    Car car = new Car("1234ABC");

    for (int i = 0; i < times; i++) {
        car.accelerate();
    }

    assertEquals(expectedSpeed, car.getSpeed());
}
📌 Aquest document pot quedar desactualitzat després d’imprimir-lo. Pots consultar la versió més recent a la pàgina web.
🌿 Abans d’imprimir aquest document, considera si és realment necessari. Redueix el consum de paper i ajuda a protegir el nostre entorn.