20050718

PHPUnit como herramienta de pruebas para programación en PHP

Le he estado dando una miradita a PHPUnit, que en definitiva me ha gustado. PHPUnit es una herramienta para la ejecución de pruebas al desarrollo de programas/sistemas efectuados específicamente en PHP. Fue desarrollada por Sebastian Bergmann.

Ciertamente, PHPUnit nació del lado de conceptos de metodologías ágiles, programación extrema, etc. como procesos de desarrollo de software (temas de los que Pra sabe un montón) y como herencia al antes desarrollado JUnit (para Java), sin embargo, no es que deba utilizarse con metodologías ágiles (esto es de lo primerito que te dicen). En definitiva es utilizable en un entorno de desarrollo como el que practicamos en InterNexo (y lo he podido comprobar.. totalmente cierto!).

Mi interés en definitiva es que podamos aplicarlo al proceso de desarrollo de sistemas de InterNexo con la idea central de fortalecer la fase de pruebas y poder garantizar de una mejor forma al cliente nuestros productos al finalizar el desarrollo de un proyecto y ante eventuales cambios que deban realizarse, lo veo sumamente importante en estos casos pues es común que quien ejecute esos cambios no es la misma persona en haber desarrollado el sistema originalmente.

Asume una programación orientada a objetos y existen versiones para PHP 4 y para PHP 5.

A continuación un pequeño ejemplo de los resultados obtenidos. Rápidamente se pueden tener resultados con tres simples archivos:

Archivo 1. clsCal.php
Este archivo es la clase, en donde se definen todos los métodos que queremos evaluar.

Archivo 2. calCase.php
Clase donde se definen las pruebas que se van a efectuar.

Archivo 3. calTest.php
Para ejecución de las pruebas y retorno de los resultados.


Código de los archivos:

clsCal.php
Es la clase más simple posible para tener una base para las pruebas.
-----------------------------------------------------------------------------------------
<?php
class Cal
{

function suma($val1, $val2) {
return $val1 + $val2;
}

function resta($val1, $val2) {
return $val1 - $val2;
}
}
?>
-----------------------------------------------------------------------------------------


calCase.php
Hay un método constructor, un método que se ejecutará antes a la ejecución de los test un método que se ejecutará posterior a éstos.
Los métodos correspondientes a los test son todos aquellos que inicien con la palabra 'test'
-----------------------------------------------------------------------------------------
<?php

require_once 'clsCal.php';
require_once 'PHPUnit.php';

class calTest extends PHPUnit_TestCase
{
// para manejar el objeto de la clase Cal
var $obj_cal;

// metodo constructor
function calTest($name) {
$this->PHPUnit_TestCase($name);
}

// metodo que predefinidamente es llamado previo a que los test sean ejecutados
function setUp() {
$this->obj_cal = new Cal();
}

// metodo que predefinidamente es llamado posterior a que los test son ejecutados
function tearDown() {
}

// test the suma function, debe retornar TRUE
function testSumaOk() {
$this->assertTrue($this->obj_cal->suma (6, 4) == 10);
}

// test the suma function, dbe retornar FALSE
function testSumaNoOk() {
$this->assertTrue($this->obj_cal->suma (6, 4) == 11);
}

// test the resta function, debe retornar TRUE
function testRestaOk() {
$this->assertTrue($this->obj_cal->resta (10, 6) == 4);
}

// test the resta function, debe retornar FALSE
function testRestaNoOk() {
$this->assertTrue($this->obj_cal->resta (10, 6) == 6);
}

}
?>
-----------------------------------------------------------------------------------------


calTest.php
El parámetro de la clase PHPUnit_TestSuite será el nombre de la clase donde se buscarán los métodos para ejecutar las pruebas.
-----------------------------------------------------------------------------------------
<?php

require_once 'calCase.php';
require_once 'PHPUnit.php';

$suite = new PHPUnit_TestSuite("calTest");
$result = PHPUnit::run($suite);

echo $result -> toString();
?>
-----------------------------------------------------------------------------------------


Al efectuar una corrida de las pruebas obtenemos los siguientes resultados:
TestCase caltest->testsumaok() passed
TestCase caltest->testrestaok() passed
TestCase caltest->testsumanook() failed: expected TRUE, actual FALSE
TestCase caltest->testrestanook() failed: expected TRUE, actual FALSE


Tener pruebas que deben retornar FALSE pueden resultar importantes, para estar seguros que el caso de prueba se está planteando adecuadamente y no está generando TRUE por algún error en el planteamiento del test.

El anterior fue un pequeño ejemplo, pero totalmente válido para los efectos. Lo importante es que es totalmente aplicable al desarrollo de nuestros sistemas.

En un inicio parece que crear el conjunto de pruebas generará mucho tiempo adicional en el desarrollo, sin embargo, luego de probar algunos casos y por la experticie que se pueda generar, creo que el tiempo generado en esta etapa va a ser relativamente corta, sobretodo por los beneficios que vamos a obtener.

Enlaces interesantes:
Versión de PHPUnit para PHP 4
Versión de PHPUnit para PHP 5
Sitio oficial de PHPUnit, p&aacute;gina de Sebastian Bergmann
PHPUnit Pocket Guide