Volver a la página principal
viernes 20 septiembre 2024
11

Cómo utilizar @dataProvider con PHPUnit

PHPUnit es una de las herramientas más populares para realizar pruebas unitarias en proyectos PHP. Uno de los métodos más eficientes para escribir pruebas reutilizables es el uso de @dataProvider, una característica de PHPUnit que permite alimentar a los métodos de prueba con diferentes conjuntos de datos.

En este artículo, exploraremos en detalle cómo utilizar @dataProvider en PHPUnit, sus ventajas y cómo implementarlo de manera efectiva para escribir pruebas más eficientes y flexibles.

¿Qué es un Data Provider en PHPUnit?

En PHPUnit, un *Data Provider* es un método que devuelve un conjunto de datos que se utilizarán como entradas para las pruebas. Este método se asocia con una prueba específica a través de la anotación @dataProvider. Cada conjunto de datos se pasa a la prueba en una ejecución separada, lo que permite que un solo método de prueba se ejecute varias veces con diferentes datos.

Esto es particularmente útil cuando tienes un escenario de prueba que debe verificarse con múltiples variaciones de entrada, como diferentes valores o combinaciones de parámetros.

Ventajas de utilizar Data Providers

El uso de @dataProvider tiene varias ventajas:

1. Código de prueba más limpio: Al evitar la duplicación de pruebas con entradas similares, el código se vuelve más fácil de mantener.

2. Facilidad de mantenimiento: Si los escenarios de prueba cambian, solo necesitas modificar los datos en un lugar.

3. Flexibilidad: Puedes ejecutar múltiples casos de prueba en un solo método, cada uno con datos diferentes.

Ejemplo básico de un Data Provider

Veamos un ejemplo simple para entender cómo funciona @dataProvider en PHPUnit. Supongamos que estamos probando una función que suma dos números.

Paso 1: Crear el método de prueba

El primer paso es definir un método de prueba que acepte parámetros. En este ejemplo, la función que vamos a probar se llama sumar() y toma dos números como entrada.

class CalculadoraTest extends \PHPUnit\Framework\TestCase
{
    /**
     * @dataProvider proveedorDeSumas
     */
    public function testSumar($a, $b, $resultadoEsperado)
    {
        $calculadora = new Calculadora();
        $this->assertEquals($resultadoEsperado, $calculadora->sumar($a, $b));
    }
}

Paso 2: Definir el Data Provider

El siguiente paso es crear un método que provea los datos. Este método debe devolver un array de arrays, donde cada sub-array contiene los parámetros que serán pasados al método de prueba.

class CalculadoraTest extends \PHPUnit\Framework\TestCase
{
    public function proveedorDeSumas()
    {
        return [
            [1, 1, 2],
            [2, 2, 4],
            [5, 5, 10],
            [-1, 1, 0],
            [0, 0, 0],
        ];
    }

    /**
     * @dataProvider proveedorDeSumas
     */
    public function testSumar($a, $b, $resultadoEsperado)
    {
        $calculadora = new Calculadora();
        $this->assertEquals($resultadoEsperado, $calculadora->sumar($a, $b));
    }
}

En este ejemplo, el método proveedorDeSumas() proporciona cinco conjuntos de datos. La prueba testSumar() se ejecutará cinco veces, cada vez utilizando un conjunto diferente de datos (los valores $a, $b y $resultadoEsperado).

Paso 3: Crear la clase a probar

Para completar el ejemplo, necesitamos la clase Calculadora con el método sumar() que realiza la suma de dos números.

class Calculadora
{
    public function sumar($a, $b)
    {
        return $a + $b;
    }
}

Resultado

Al ejecutar las pruebas, PHPUnit ejecutará el método testSumar() cinco veces, una vez para cada conjunto de datos que proporciona el método proveedorDeSumas().

PHPUnit 9.5.0 by Sebastian Bergmann and contributors.

.....                                                           5 / 5 (100%)

Time: 00:00.012, Memory: 4.00 MB

OK (5 tests, 5 assertions)

Uso avanzado de Data Providers

El ejemplo anterior es muy básico. Sin embargo, puedes aprovechar @dataProvider de maneras más avanzadas para manejar casos más complejos.

Data Providers con diferentes tipos de datos

Puedes probar tu código con diferentes tipos de datos (enteros, cadenas, booleanos, etc.) para asegurarte de que funcione en una variedad de situaciones.

public function proveedorDeDatosMixtos()
{
    return [
        [1, "1", 2],  // Suma de un entero y una cadena
        [true, 1, 2], // Suma de un booleano y un entero
        [null, 0, 0], // Suma de null y un entero
    ];
}

Reutilización de Data Providers entre pruebas

Un solo Data Provider puede ser utilizado por múltiples métodos de prueba. Esto es útil si varios métodos de prueba requieren conjuntos de datos similares.

public function testMultiplicar($a, $b, $resultadoEsperado)
{
    $calculadora = new Calculadora();
    $this->assertEquals($resultadoEsperado, $calculadora->multiplicar($a, $b));
}

/**
 * @dataProvider proveedorDeSumas
 */
public function testSumar($a, $b, $resultadoEsperado)
{
    $calculadora = new Calculadora();
    $this->assertEquals($resultadoEsperado, $calculadora->sumar($a, $b));
}

En este caso, tanto testSumar() como testMultiplicar() podrían compartir el mismo @dataProvider.

Data Providers con métodos estáticos

Es posible que desees utilizar métodos estáticos para los Data Providers, especialmente si el método no necesita acceder a ninguna propiedad de la clase.

public static function proveedorEstatico()
{
    return [
        [1, 1, 2],
        [2, 2, 4],
        [3, 3, 6],
    ];
}

Recuerda que, si usas un método estático como Data Provider, la anotación @dataProvider debe referirse al método de la misma manera:

/**
 * @dataProvider proveedorEstatico
 */
public function testSumar($a, $b, $resultadoEsperado)
{
    $calculadora = new Calculadora();
    $this->assertEquals($resultadoEsperado, $calculadora->sumar($a, $b));
}

Manejo de excepciones en Data Providers

Puedes utilizar @dataProvider para probar también situaciones en las que se espera que tu código arroje excepciones. Veamos un ejemplo donde el método sumar() debería lanzar una excepción si se intenta sumar un valor no numérico.

public function proveedorDeExcepciones()
{
    return [
        [1, 'a'],   // Una cadena no numérica
        [null, 2],  // null como parámetro
        [[], 3],    // Un array como parámetro
    ];
}

/**
 * @dataProvider proveedorDeExcepciones
 */
public function testSumaConExcepciones($a, $b)
{
    $this->expectException(\InvalidArgumentException::class);
    $calculadora = new Calculadora();
    $calculadora->sumar($a, $b);
}

En este ejemplo, el Data Provider proveedorDeExcepciones() entrega casos en los que el método sumar() debe arrojar una excepción debido a parámetros inválidos.

Conclusión

El uso de @dataProvider en PHPUnit es una práctica recomendada para crear pruebas más eficientes y fáciles de mantener. Al aprovechar esta funcionalidad, puedes probar tu código con múltiples conjuntos de datos sin duplicar código, lo que resulta en pruebas más limpias y robustas.

Ya sea que estés probando simples operaciones matemáticas, validando entradas mixtas o verificando que se manejen correctamente las excepciones, @dataProvider te proporciona la flexibilidad que necesitas para mejorar la cobertura y calidad de tus pruebas. ¡Implementa Data Providers en tu próximo proyecto y observa cómo mejora tu flujo de trabajo de pruebas! 🤙

Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer