PHP

PHP

Tutorial PHP: PHPUnit

PHPUnit Instalación y Configuración: Aprende a instalar y configurar PHPUnit para pruebas unitarias en PHP usando Composer. Ideal para desarrolladores.

Aprende PHP GRATIS y certifícate

Instalación y configuración de PHPUnit

Para comenzar a realizar pruebas unitarias en PHP, es esencial instalar PHPUnit, una de las herramientas más utilizadas para este fin. A continuación, se detallan los pasos para instalar y configurar PHPUnit utilizando Composer, el gestor de dependencias estándar en PHP.

Requisitos previos

Antes de proceder con la instalación, asegúrese de tener instalado:

  • PHP en su versión 8.3 o superior.
  • Composer instalado globalmente en su sistema.

Instalación de PHPUnit mediante Composer

  1. Crear un directorio de proyecto y navegar hasta él:
mkdir mi_proyecto
cd mi_proyecto
  1. Inicializar Composer en el directorio del proyecto:
composer init --require=phpunit/phpunit ^10.0 --no-interaction

Esto crea un archivo composer.json con PHPUnit como dependencia.

  1. Instalar PHPUnit ejecutando:
composer install

Composer descargará y ubicará PHPUnit en el directorio vendor.

Configuración del entorno de pruebas

Para facilitar la ejecución de las pruebas, es recomendable agregar un script en el archivo composer.json:

{
    "scripts": {
        "test": "phpunit"
    }
}

Ahora, podrá ejecutar las pruebas simplemente con:

composer test

Verificación de la instalación

Para confirmar que PHPUnit se ha instalado correctamente, ejecute:

vendor/bin/phpunit --version

Debería obtener una respuesta similar a:

PHPUnit 10.0.0 by Sebastian Bergmann and contributors.

Nota: Asegúrese de que el archivo phpunit tenga permisos de ejecución.

Configuración de PHPUnit

Para personalizar el comportamiento de PHPUnit, cree un archivo de configuración phpunit.xml en la raíz del proyecto:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php" colors="true">
    <testsuites>
        <testsuite name="Mi Test Suite">
            <directory>tests</directory>
        </testsuite>
    </testsuites>
</phpunit>

Este archivo indica a PHPUnit que cargue el autoloader de Composer y que busque las pruebas en el directorio tests.

Estructura de directorios

Organice su proyecto de la siguiente manera:

  • src/: Contendrá el código fuente de la aplicación.
  • tests/: Incluirá todos los archivos de prueba de PHPUnit.

Ejemplo:

mi_proyecto/
├── composer.json
├── phpunit.xml
├── src/
│   └── Calculadora.php
└── tests/
    └── CalculadoraTest.php

Ejemplo básico

Cree una clase simple en src/Calculadora.php:

<?php

namespace App;

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

Luego, escriba una prueba unitaria en tests/CalculadoraTest.php:

<?php

use PHPUnit\Framework\TestCase;
use App\Calculadora;

class CalculadoraTest extends TestCase
{
    public function testSumar()
    {
        $calculadora = new Calculadora();
        $resultado = $calculadora->sumar(2, 3);
        $this->assertEquals(5, $resultado);
    }
}

Ejecutar las pruebas

Finalmente, execute las pruebas con:

composer test

Si todo está configurado correctamente, verá una salida que indica que las pruebas han pasado:

OK (1 test, 1 assertion)

Servidor web integrado

Para complementar las pruebas y ejecutar su aplicación, puede utilizar el servidor web integrado de PHP:

php -S localhost:8000 -t public

Esto levantará un servidor local en el puerto 8000, sirviendo los archivos desde el directorio public.

Consideraciones finales

  • Mantenga sus dependencias actualizadas ejecutando composer update.
  • Utilice namespaces y el autoloading de Composer para organizar su código.
  • Aproveche las opciones de configuración de PHPUnit para adaptar las pruebas a sus necesidades.

Con esta configuración, estará listo para desarrollar y probar aplicaciones PHP de manera eficiente y profesional.

Estructura de un test: métodos setUp, tearDown, aserciones (assertEquals, assertTrue, etc.)

Al desarrollar pruebas unitarias con PHPUnit, es fundamental comprender la estructura básica de un test y cómo utilizar los métodos y aserciones proporcionados por el framework. Un test en PHPUnit es una clase que hereda de PHPUnit\Framework\TestCase y contiene métodos que comienzan con la palabra clave test.

Clase de prueba y métodos de test

Cada clase de prueba representa una unidad de código a probar y puede contener múltiples métodos de prueba. Por convención, los métodos de prueba deben comenzar con test, lo que permite a PHPUnit reconocerlos automáticamente.

<?php

use PHPUnit\Framework\TestCase;

class MiClaseTest extends TestCase
{
    public function testAlgo()
    {
        // Código de prueba
    }
}

En este ejemplo, testAlgo es un método de prueba que evaluará una funcionalidad específica. Es importante que cada método de prueba sea independiente y no dependa de la ejecución de otros tests.

Métodos setUp y tearDown

Los métodos setUp y tearDown permiten configurar y limpiar el ambiente antes y después de cada test, respectivamente. El método setUp se ejecuta antes de cada prueba y es ideal para inicializar objetos o variables necesarios en múltiples tests. El método tearDown se ejecuta después de cada prueba y se utiliza para liberar recursos o restablecer estados.

<?php

use PHPUnit\Framework\TestCase;

class UsuarioTest extends TestCase
{
    private $usuario;

    protected function setUp(): void
    {
        $this->usuario = new Usuario();
    }

    protected function tearDown(): void
    {
        unset($this->usuario);
    }

    public function testNombreUsuario()
    {
        $this->usuario->setNombre('Juan');
        $this->assertEquals('Juan', $this->usuario->getNombre());
    }
}

En este caso, setUp crea una nueva instancia de Usuario antes de cada test, y tearDown elimina la referencia al objeto después de cada test. Esto asegura que cada prueba se ejecute en un ambiente controlado y aislado.

Aserciones en PHPUnit

Las aserciones son métodos que permiten verificar si un valor cumple con una condición específica. PHPUnit ofrece una variedad de aserciones para diferentes tipos de comprobaciones.

assertEquals

Comprueba si dos valores son iguales. Es útil para verificar resultados esperados.

$this->assertEquals(10, $resultado);

Aquí se verifica que $resultado sea igual a 10.

assertTrue y assertFalse

Verifican si una condición es verdadera o falsa, respectivamente.

$this->assertTrue($usuario->esActivo());
$this->assertFalse($usuario->esAdmin());

Estos métodos comprueban el estado booleano de las funciones esActivo() y esAdmin().

assertNull y assertNotNull

Comprueban si un valor es null o no.

$this->assertNull($usuario->getApellido());

Esta aserción verifica que getApellido() devuelve null.

assertContains

Verifica que un elemento esté presente en un array o cadena de texto.

$this->assertContains('admin', $roles);

Se asegura de que 'admin' esté dentro del array $roles.

assertInstanceOf

Comprueba que un objeto es instancia de una clase específica.

$this->assertInstanceOf(Usuario::class, $this->usuario);

Esta aserción confirma que $this->usuario es una instancia de Usuario.

Ejemplo completo

A continuación, se presenta un ejemplo completo que ilustra el uso de setUp, tearDown y varias aserciones.

<?php

use PHPUnit\Framework\TestCase;

class CarritoTest extends TestCase
{
    private $carrito;

    protected function setUp(): void
    {
        $this->carrito = new Carrito();
    }

    protected function tearDown(): void
    {
        unset($this->carrito);
    }

    public function testAgregarProducto()
    {
        $producto = new Producto('Manzana', 1.5);
        $this->carrito->agregarProducto($producto);
        $this->assertCount(1, $this->carrito->getProductos());
        $this->assertContains($producto, $this->carrito->getProductos());
    }

    public function testCalcularTotal()
    {
        $producto1 = new Producto('Pan', 0.8);
        $producto2 = new Producto('Leche', 1.2);
        $this->carrito->agregarProducto($producto1);
        $this->carrito->agregarProducto($producto2);
        $total = $this->carrito->calcularTotal();
        $this->assertEquals(2.0, $total);
        $this->assertNotNull($total);
    }
}

En este ejemplo, setUp inicializa un nuevo Carrito antes de cada test, y tearDown libera los recursos después. Se utilizan aserciones como assertCount, assertContains, assertEquals y assertNotNull para validar el comportamiento del carrito de compras.

Buenas prácticas al escribir tests

  • Nombrar claramente los métodos de prueba para reflejar lo que están verificando.
  • Mantener los tests simples y específicos, probando una sola funcionalidad por test.
  • Utilizar los métodos setUp y tearDown para evitar duplicar código y preparar el ambiente adecuadamente.
  • Emplear aserciones que proporcionen información clara en caso de fallo, lo que facilita el diagnóstico de errores.

Ejecutando los tests

Para ejecutar las pruebas, utilice el comando de PHPUnit o el script definido en composer.json:

composer test

Al hacerlo, PHPUnit ejecutará todos los métodos de prueba y proporcionará un informe detallado de los resultados.

Resumen de aserciones comunes

A continuación, se muestra una tabla con algunas aserciones frecuentes:

Aserción Descripción
assertEquals($esperado, $actual) Verifica que dos valores son iguales
assertTrue($condición) Comprueba que una condición es verdadera
assertFalse($condición) Comprueba que una condición es falsa
assertNull($valor) Verifica que un valor es null
assertNotNull($valor) Verifica que un valor no es null
assertContains($elemento, $array) Comprueba que un elemento está en un array o cadena
assertCount($conteo, $array) Verifica el número de elementos en un array
assertInstanceOf($clase, $objeto) Comprueba que un objeto es instancia de una clase

Estas aserciones permiten validar diferentes tipos de condiciones y son herramientas esenciales para garantizar la calidad y fiabilidad del código.

Utilizando el servidor integrado de PHP

Para probar su aplicación en conjunto con las pruebas unitarias, puede iniciar el servidor web integrado:

php -S localhost:8000

Esto levanta un servidor local en el puerto 8000, lo que facilita el desarrollo y la verificación inmediata de los cambios realizados.

Entender la estructura de un test en PHPUnit y saber utilizar los métodos setUp, tearDown y las diversas aserciones es fundamental para escribir pruebas unitarias efectivas. La implementación de estas prácticas contribuye a desarrollar código más robusto y mantenible.

Creación y ejecución de pruebas unitarias con PHPUnit

Una vez que PHPUnit está correctamente instalado y configurado, es momento de crear y ejecutar pruebas unitarias para garantizar la calidad del código. A continuación, se detallan los pasos y buenas prácticas para desarrollar pruebas efectivas utilizando PHPUnit.

Creando una clase de prueba

Para comenzar, debe ubicar sus pruebas en el directorio designado, típicamente tests/. Cada clase de prueba debe cubrir una clase o funcionalidad específica de su aplicación. La clase de prueba debe extender de PHPUnit\Framework\TestCase.

<?php

use PHPUnit\Framework\TestCase;

class CalculadoraTest extends TestCase
{
    // Métodos de prueba irán aquí
}

Escribiendo métodos de prueba

Los métodos de prueba deben comenzar con la palabra clave test o tener la anotación @test. Cada método debe probar una funcionalidad aislada y contener aserciones que validen el comportamiento esperado.

<?php
public function testSuma()
{
    $calculadora = new Calculadora();
    $resultado = $calculadora->sumar(2, 3);
    $this->assertEquals(5, $resultado);
}

En este ejemplo, el método testSuma verifica que el método sumar de la clase Calculadora devuelve el resultado correcto. La aserción assertEquals compara el valor esperado con el valor actual.

Utilizando diferentes aserciones

PHPUnit ofrece una variedad de aserciones para validar distintos aspectos del código. Al escribir pruebas, es importante escoger la aserción adecuada para cada caso.

  • assertSame($esperado, $actual): Verifica que dos variables son iguales y del mismo tipo.
  • assertContains($elemento, $arreglo): Comprueba que un elemento está presente en un arreglo.
  • assertEmpty($variable): Verifica que una variable está vacía.
  • assertInstanceOf($clase, $objeto): Verifica que un objeto es instancia de una clase específica.

Ejemplo:

<?php
public function testEsPar()
{
    $numero = 4;
    $this->assertTrue($this->esPar($numero));
}

private function esPar($numero)
{
    return $numero % 2 === 0;
}

Aquí, la aserción assertTrue valida que el método esPar devuelve true para un número par.

Organizando las pruebas

Es recomendable organizar las pruebas de manera coherente para facilitar su mantenimiento. Puede agrupar los métodos de prueba por funcionalidad o por métodos de la clase a probar.

<?php
public function testResta()
{
    $calculadora = new Calculadora();
    $resultado = $calculadora->restar(5, 2);
    $this->assertEquals(3, $resultado);
}

public function testMultiplicacion()
{
    $calculadora = new Calculadora();
    $resultado = $calculadora->multiplicar(3, 4);
    $this->assertEquals(12, $resultado);
}

Además, es importante nombrar los métodos de prueba de forma que reflejen claramente lo que están verificando.

Pruebas con diferentes escenarios

Para garantizar una cobertura completa, es útil probar diferentes escenarios, incluyendo casos límite y entradas inválidas.

<?php
public function testDivisionPorCero()
{
    $this->expectException(DivisionPorCeroException::class);
    
    $calculadora = new Calculadora();
    $calculadora->dividir(10, 0);
}

En este ejemplo, se utiliza expectException para verificar que se lanza una excepción al intentar dividir por cero.

Ejecutando las pruebas

Para ejecutar las pruebas, puede utilizar el comando de PHPUnit directamente o a través de Composer si se ha configurado un script.

Ejecutando directamente:

vendor/bin/phpunit

Ejecutando a través de Composer:

composer test

PHPUnit buscará automáticamente las clases de prueba y ejecutará todos los métodos que cumplen con los criterios. La salida mostrará el progreso y los resultados de las pruebas.

Analizando los resultados

Al ejecutar las pruebas, PHPUnit proporciona un resumen detallado:

  • Un punto . indica una prueba pasada.
  • Una letra F indica una prueba fallida.
  • Una letra E indica un error durante la prueba.

Ejemplo de salida:

PHPUnit 10.0.0 by Sebastian Bergmann and contributors.

..F.

Time: 00:00.025, Memory: 4.00 MB

There was 1 failure:

1) CalculadoraTest::testMultiplicacion
Failed asserting that 11 matches expected 12.

/tests/CalculadoraTest.php:25

FAILURES!
Tests: 4, Assertions: 4, Failures: 1.

En este caso, la prueba testMultiplicacion ha fallado porque el resultado esperado era 12, pero se obtuvo 11. Es crucial revisar estos mensajes para corregir los errores en el código o en las pruebas.

Utilizando opciones de PHPUnit

Puede personalizar la ejecución de las pruebas utilizando opciones en la línea de comandos:

  • --filter: Ejecuta pruebas que coinciden con un patrón específico.
vendor/bin/phpunit --filter testSuma
  • --verbose: Proporciona una salida más detallada.
vendor/bin/phpunit --verbose
  • --bootstrap: Especifica un archivo de inicialización.
vendor/bin/phpunit --bootstrap vendor/autoload.php

Pruebas automatizadas con PHPUnit y scripts

Para integrar las pruebas en su flujo de trabajo, puede utilizar scripts que ejecuten las pruebas automáticamente. Por ejemplo, puede configurar un script en composer.json que ejecute las pruebas cada vez que se realice cierta acción.

{
    "scripts": {
        "test": "phpunit",
        "pre-commit": "composer test"
    }
}

De esta manera, al ejecutar composer test o antes de realizar un commit, las pruebas se ejecutarán automáticamente, ayudando a detectar errores tempranamente.

Integración con sistemas de control de versiones

Es una buena práctica integrar las pruebas unitarias con sistemas de integración continua (CI) como GitHub Actions, GitLab CI/CD o Jenkins. Esto permite que las pruebas se ejecuten automáticamente en cada push o merge request, asegurando que el código en el repositorio cumple con los estándares de calidad.

Buenas prácticas en pruebas unitarias

  • Independencia: Cada prueba debe ser independiente de las demás y no debe depender del orden de ejecución.
  • Repetibilidad: Las pruebas deben dar los mismos resultados cada vez que se ejecutan bajo las mismas condiciones.
  • Claridad: Los nombres de las pruebas y los mensajes de aserción deben ser claros y descriptivos.
  • Cobertura: Procure cubrir tantos caminos de ejecución como sea posible, incluyendo casos de error y excepciones.

Utilizando el servidor web integrado para pruebas funcionales

Si necesita realizar pruebas que involucren interacciones a nivel de aplicación o web, puede utilizar el servidor web integrado de PHP:

php -S localhost:8000

Este servidor permite servir su aplicación localmente en el puerto 8000, facilitando la ejecución de pruebas funcionales o manuales.

Ejemplo avanzado con datos de prueba

Para probar un método con múltiples conjuntos de datos, puede utilizar el enfoque de proveedores de datos.

<?php
/**
 * @dataProvider proveedorDeSuma
 */
public function testSumaConDatos($a, $b, $esperado)
{
    $calculadora = new Calculadora();
    $resultado = $calculadora->sumar($a, $b);
    $this->assertEquals($esperado, $resultado);
}

public function proveedorDeSuma()
{
    return [
        [1, 2, 3],
        [0, 0, 0],
        [-1, -1, -2],
        [PHP_INT_MAX, 0, PHP_INT_MAX],
    ];
}

En este ejemplo, la anotación @dataProvider indica que el método proveedorDeSuma suministra diferentes conjuntos de datos para el test, permitiendo validar múltiples casos con un solo método de prueba.

Para seguir leyendo hazte Plus

¿Ya eres Plus? Accede a la app

20 % DE DESCUENTO

Plan mensual

19.00 /mes

15.20 € /mes

Precio normal mensual: 19 €
58 % DE DESCUENTO

Plan anual

10.00 /mes

8.00 € /mes

Ahorras 132 € al año
Precio normal anual: 120 €
Aprende PHP GRATIS online

Todas las lecciones de PHP

Accede a todas las lecciones de PHP y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Php

PHP

Introducción Y Entorno

Instalación Y Primer Programa De Php

PHP

Introducción Y Entorno

Tipos De Datos, Variables Y Constantes

PHP

Sintaxis

Operadores Y Expresiones

PHP

Sintaxis

Estructuras De Control

PHP

Sintaxis

Funciones Y Llamada De Funciones

PHP

Sintaxis

Cadenas De Texto Y Manipulación

PHP

Sintaxis

Manejo De Números

PHP

Sintaxis

Manejo De Fechas Y Tiempo

PHP

Sintaxis

Manejo De Arrays

PHP

Sintaxis

Introducción A La Poo En Php

PHP

Programación Orientada A Objetos

Clases Y Objetos

PHP

Programación Orientada A Objetos

Constructores Y Destructores

PHP

Programación Orientada A Objetos

Herencia

PHP

Programación Orientada A Objetos

Encapsulación

PHP

Programación Orientada A Objetos

Polimorfismo

PHP

Programación Orientada A Objetos

Interfaces

PHP

Programación Orientada A Objetos

Traits

PHP

Programación Orientada A Objetos

Namespaces

PHP

Programación Orientada A Objetos

Autoloading De Clases

PHP

Programación Orientada A Objetos

Manejo De Errores Y Excepciones

PHP

Programación Orientada A Objetos

Manejo De Archivos

PHP

Programación Orientada A Objetos

Patrones De Diseño

PHP

Programación Orientada A Objetos

Introducción A Los Formularios En Php

PHP

Formularios

Procesamiento De Datos De Formularios

PHP

Formularios

Manejo De Archivos En Formularios

PHP

Formularios

Redirecciones Y Retroalimentación Al Usuario

PHP

Formularios

Formularios Dinámicos Y Separación De Lógica

PHP

Formularios

Introducción A La Persistencia En Php

PHP

Persistencia

Conexión A Bases De Datos

PHP

Persistencia

Consultas Y Operaciones Crud

PHP

Persistencia

Gestión De Transacciones

PHP

Persistencia

Manejo De Errores Y Excepciones En Base De Datos

PHP

Persistencia

Patrones De Acceso A Datos

PHP

Persistencia

Concepto De Sesiones En Php

PHP

Sesiones Y Cookies

Configuración De Sesiones

PHP

Sesiones Y Cookies

Cookies

PHP

Sesiones Y Cookies

Manejo Avanzado De Sesiones Y Cookies

PHP

Sesiones Y Cookies

Principales Vulnerabilidades En Php

PHP

Seguridad

Seguridad En Formularios Y Entrada De Datos

PHP

Seguridad

Protección Frente A Inyección Sql

PHP

Seguridad

Gestión De Contraseñas Y Cifrado

PHP

Seguridad

Seguridad En Sesiones Y Cookies

PHP

Seguridad

Configuraciones De Php Para Seguridad

PHP

Seguridad

Introducción Al Testing En Php

PHP

Testing

Phpunit

PHP

Testing

Cobertura De Código En Testing

PHP

Testing

Test Doubles (Mocks, Stubs, Fakes, Spies)

PHP

Testing

Pruebas De Integración Y Funcionales

PHP

Testing

Accede GRATIS a PHP y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Instalar PHPUnit usando Composer.
  • Configurar entorno de pruebas en PHP.
  • Crear archivo composer.json con PHPUnit como dependencia.
  • Añadir scripts de ejecución de pruebas en Composer.
  • Verificar instalación de PHPUnit correctamente.
  • Configuración personalizada de PHPUnit con phpunit.xml.