Haciendo del Desarrollo y la Arquitectura Web, ciencia y pasión.

PHPUnit sobre Codeigniter

Como todos los frameworks, Codeigniter puede trabajar con Phpunit para poder desarrollar una plataforma de testeo de nuestra aplicación. En este articulo vamos a hablar de como instalarlo y configurarlo. Para empezar necesitaremos ambos instalados, CodeIgniter y PHPunit. El primero lo descargaremos de la web en un comprimido, no tiene ninguna ciencia, se se descarga, se descomprime y listo. El segundo lo instalaremos via composer. Lo primero es crear nuestro archivo composer.json. Este archivo sera el que alimente el comando composer, que tendrás que instalar. si ya existiera el archivo json solo faltaria asegurarse de que tenemos la linea con la version adecuada de phpunit


{
  "require-dev": {
    "phpunit/phpunit": "4.* || 5.*"
  }
}

Una vez creado el archivo en el raiz de nuestro proyecto le damos a composer:



daniel@botijito:~/proyectos/proy_phpunit$ composer install Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 26 installs, 0 updates, 0 removals - Installing mikey179/vfsstream (v1.1.0): Loading from cache ... - Installing phpunit/phpunit (5.5.4): Loading from cache

Este comando actulizara los paquetes que integran nuestra version de codeigniter y automaticamente nos creará una carpeta vendor dentro de nuestro proyecto con el ejecutable, etc. ahora disponemos del ejecutable bajo /verndor/bin/phpunit


daniel@botijito:~/proyectos/proy_phpunit$ ./vendor/bin/phpunit --version
PHPUnit 5.5.4 by Sebastian Bergmann and contributors.

Siguiente paso, creamos un phpunit.xml.dist:

<?xml version="1.0" encoding="UTF-8"?>

<phpunit
colors="true"
stopOnFailure="false"
backupGlobals="false"
backupStaticAttributes="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
syntaxCheck="false"
cacheTokens="true"
verbose="false"
bootstrap="tests/Bootstrap.php">
<testsuites>
<testsuite name="CITools Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>./system/</directory>
</whitelist>
</filter>
</phpunit>

Lo siguiente sera crear un archivo de arranque para phpunit, asi que copiaremos el index.php sobre bootstrap.php, para ello haremos:


cp index.php ./tests/bootstrap.php

Al haber movido el bootstrap a la carpeta tests tenemos que hacer dos cambios para que la carpeta app y system no se queden mal referenciadas:


Cambiaremos $system_path = '../system'; y $application_folder = '../application';

Y por otro lado cambiar el entorno a testing:


define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'testing');

Perfecto, ahora tenemos que hacer que la salida se procese correctamente, para lo cual crearemos un hook de captura de la salida: Primero habilitamos los hooks en nuestro application/config/config.php:


 $config['enable_hooks'] = TRUE

A continuación damos de alta un hook en application/config/hooks.php


 $hook['display_override'] = array(
    'class' => 'DisplayHook',
    'function' => 'captureOutput',
    'filename' => 'DisplayHook.php',
    'filepath' => 'hooks'
  );

Y daremos el siguiente codigo a nuestro hook en application/hooks/DisplayHook.php. Este hook se ejecutará cuando se vaya a imprimir algo, pero solamente cuando nuestro entorno no sea testing.


class DisplayHook
{
	public function captureOutput()
	{
		$this->CI =& get_instance();
		$output = $this->CI->output->get_output();

		if (ENVIRONMENT != 'testing') {
			echo $output;
		}
	}
}

Ahora vamos con el test en sí, pero antes sería menester tener algo que testear. Creamos rapidamente un modelo super sencillo que va a sumar los elementos de un array. asi que vamos a la carpeta models y creamos una clase que tendrá un esta función tal que así:


class CalculadoraModel  extends CI_model{
    
    function sumaData(Array $data){
        $ac =0;
        foreach ($data as $op){
            $ac = $ac + $op;
        }
        return $ac;
    }

}

Y ahora vamos con el test


 class CITest extends PHPUnit_Framework_TestCase
  {
    private $CI;
    public function setUp()
    {
      // Load CI instance normally
      $this->CI = &get_instance();
      $this->CI->load->model ('CalculadoraModel');
    }
    public function testsuma()
    {
       $data = array(1,2,3);
       $this->assertEquals(6, $this->CI->CalculadoraModel->sumaData($data));
    }
  }

como todos los tests tiene un setup que se ejecutará al principio del cada test. En éste se instancia el objeto con el que podremos cargar nuestra calculadora. Y a continuacion un test que verificara que cuando le pasamos un array que suma 6 devuelve un 6. Ejecutamos phpunit y vemos que ha ejecutado un test con un assert y que todo ha ido bien nuestro código está bien como dice phpunit.


daniel@botijito:~/proyectos/proy_phpunit$ ./vendor/bin/phpunit
PHPUnit 5.5.4 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 317 ms, Memory: 4.00MB

OK (1 test, 1 assertion)