Test Unitarios en Cakephp

 

cakePhp

Podreís ver que muchos de mis Posts son sobre cakephp, pero es sobre lo que estoy trabajando ahora mismo.

En este caso me gustaría Explicar como hacer un test unitario en un módelo y su importancia.
A mi me ayuda mucho. No se siempre, si mi modelo está bien hecho, también me ayuda a pensar en todas las funciones que necesito para ese modelo, en diferentes casos que puedo tener de respuesta, y no dar palos de ciego cuando algo no funciona.
Aunque al principio pueda parecer una perdida de tiempo hacer test unitarios, cuando la complegidad se mayor más los necesitaremos, y nos daremos cuenta de que nuestro rendimiento mejora.

Lo primero que deberemos hacer, es crear un fixture, vamos a poner un ejemplo simple, un modelo User con los campos id, name, email.

En el directorio tests/fixtures creamos el archivo user_fixtures.php
En este fichero siempre tendremos que tener la extructura de nuestra tabla, y datos con los que luego haremos nuestros tests.

ejemplo user_fixtures.php

class UserFixture extends CakeTestFixture {
	var $name = 'User';
	var $table = 'users';
	var $fields = array(
		'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'length' => 20, 'key' => 'primary'),
		'name' => array('type'=>'string', 'null' => false, 'default' => NULL, 'length' => 100),
		'email' => array('type'=>'string', 'null' => false, 'default' => NULL),
		'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
	);
	var $records = array(
		array(
		'id'  => 1,
		'name'  => 'usuario1',
		'email'  => 'usuario1@email.com'),
	var $records = array(
		array(
		'id'  => 2,
		'name'  => 'usuario2',
		'email'  => 'usuario2@email.com'),
	);
}

Una vez hecho el fixture, es momento de pensar en nuestros en un caso de test unitario, el primero que se me ocurre es buscar usuarios por su id.
Creamos en el directorio tests/models el archivo user.test.php, importante siempre en cake el nombre de los arhivos.
Ejemplo user.test.php

App::import('Model', 'user');

class UserTestCase extends CakeTestCase {
	var $user = null;
	var $fixtures = array('app.user');

	function startTest() {
		$this-=>User =& ClassRegistry::init('User');
	}
        function testuserInstance() {
		$this-=>assertTrue(is_a($this-=>User, 'User'));
	}
        function testfindUserId(){
	        // buscamos en el modelo user en la función findUserId la id 1.
		$friendid=$this-=>User-=>findUserId(1);
                // comparamos si el usuario el name de la busqueda, con usuario1, que debería ser true.
		$this-=>assertEqual($friendid['User']['name'],'usuario1');
	}
}

Ya tenemos Hecho un test unitario para el modelo User, ahora mismo esto nos dará Error, debemos crear la funcion findUserId() en el modelos user, aún así nos dará error, hay que hacer que esta función nuestro return sea el usuario 1 que es lo que estamos buscando.
Por cierto para poder hacer test en Cakephp debemos tener el debug del core.php a 2.

  • Hola, me estoy adentrando en esto de hacer tests para aplicaciones web en cakephp, pero no estoy viendo mucho la utilidad o como esto me puede ayudar a controlar que mis modelos y controladores estén bien implementados, me gustaría que me contases como has aplicado vos estos test con algunos ejemplos de uso, no hace falta un código de ejemplo, basta con describirme problemas en los cual los aplicaste, para entender mas jugando un poco con el ejemplo que siempre sirve para complementar la teoría, y si podrías postear algún ejemplo de un testeo de una vista (no supe como aplicar el testeo de vistas leyendo del manual oficial de cake), muchas gracias.

  • deldan

    hola buenas, creo entender que la parte de código la sabes, pero no sabes el porque o para que aplicarla, te doy un ejemplo de como y para que lo uso.

    yo lo uso principalmente para modelos, que creo con el script bake, no me haría falta los test si en los modelos solo tuviese lo que me crea el bake ( insertar, modificar, eliminar), normalmente tengo que modificar estas funciones y añadir otras, en el caso de gestión de usuarios tipica, tengo que añadir por ejmplo la funcion activarcuenta(), para cuando el usuario se registra y recibe el mail de bienvenida, el test me ayuda a que este paso funciona en modelo, ya me despreucupo si tengo un problema debe estar en controlador o vista, esto es un ejemplo sencillo, pero la cosa se complica en cuando no hago un test de modelo, cuando es algo más complejo, y en vez de test, tengo que tener el controlador y la vista construidos y probar en la web, a ver los fallos, puedes perde mucho tiempo. Me ha pasado en una especia de correo online en una aplicación, y creeme habría deseado tener los test, si son cosas sencillas nos podemos olvidar, ahora cuando nuestro modelo se complica, lo veo de mucha utilidad.

    espero que te haya servido. un saludo

  • Hola, muchas gracias por la respuesta, dejame ver si entendí la idea, osea, entiendo que quisiste decir que la función de activar cuenta esta en algún controlador que hace esta lógica para un usuario que crea una cuenta nueva; luego entiendo que haces una función en el test del modelo de user la cual realiza una serie de asserts verificando que este usuario ahora si esta validado y su cuenta ha sido activada (quizás también usando algún fixture para no romper tus datos originales), y así podes verificar si tu función del controlador hizo todo de manera correcta ya que en el modelo tu test se realizó correctamente; de no ser así tendrías un error en algún controlador que tendrías que revisar, ¿esto es correcto?. Muchas gracias.

  • deldan

    si es todo correcto, excepto, en lo de activar cuenta, tengo una función en el modelo, que tendrá algo asi $this->saveField(‘active’,’1′); por ejemplo, entonces compruebo con el test, que esto funciona, aquí no tendría cosas en el ficture, tan solo le diría si esto me da true, y ya está.

    se que este ejmplo es muy sencillo, peor esta es la idea.

    si el test te da ok, y hay algun fallo, hay tres posibilidades, que el controlador este mal, o quizás la vista, o que el test que tengas esté mal hecho. jeje esto también me ha pasado.

    un saludo

  • perfecto, gracias che, saludos!

  • deldan

    denada, saludos para ti también!

  • decir que para poder acceder a los tests es el enlace tipo (http:://tusite.net/test.php y/o http://localhost/test.php)