Entradas en la categoría “Desarrollo”

Tests para formularios HTML con Watir

25 de agosto, 2011 - por | 2 comentarios | Desarrollo, QA

Modelar nos ayuda a adelantar problemas futuros. Es igual que lo hagamos con plastilina, madera o tests.

Aunque nosotros no tenemos una orientación fuerte hacia los tests, en el sentido de considerarlos una parte esencial de cualquiera de nuestros proyectos, sí que los incorporamos cuando entendemos que nos vienen bien. Ésto ocurre sobre todo en proyectos de larga duración, con múltiples funcionalidades, y en constante crecimiento.

Cuando se dan esas ocasiones, utilizamos las siguientes herramientas:

  • el framework PHPUnit para código PHP
  • el framework unittest para código Python
  • el framework Watir para tests basados en el navegador

Hoy queremos hablar un poco del último, ofreciendo un ejemplo de cómo lo utilizamos.

Instalar Watir (Web Application Testing in Ruby)

Watir es una gema de Ruby, por lo que lo primero que tienes que tener funcionando en tu máquina es Ruby. Tienes toda la información necesaria en la página oficial de Ruby.

Con Ruby funcionando, en un entorno Linux como el nuestro, la instalación de Watir requiere primero tener instaladas las rubygems. A partir de ahí, instalamos Watir:


sudo gem install watir-webdriver

Para cualquier otro entorno, o ver más información sobre detalles de la instalación, consulta la documentación oficial de Watir (en inglés).

Test para un formulario HTML

Un caso habitual en los tests basados en el navegador son los formularios. Por ejemplo, piensa en el siguiente formulario, que es una captura de uno de nuestros proyectos.

Captura del formulario sobre el que se hace el test.

En este típico formulario hay 2 campos (‘Title’ ‘Comment’) y un botón de envío (‘send’). Con Watir podemos montar un test sencillo que compruebe, por ejemplo, que el proceso de añadir un comentario está funcionando correctamente.

Cuando escribes un test basado en el navegador, tus 2 recursos principales son la URL y el HTML. Con la primera obtienes la página que quieres testear, y con todo el documento HTML de esa página puedes empezar a establecer las evaluaciones que quieres probar. En nuestro ejemplo, la parte que nos interesa del HTML, es la que afecta al formulario que acabamos de mostrar. Así que una aproximación razonable sería rellenar ese formulario con datos de prueba y realizar el envío.

Creamos un fichero, lo nombramos como test_review_form.rb, y lo iniciamos con el siguiente código.


# Test for Biz Review
require 'rubygems'
require 'watir-webdriver'
b = Watir::Browser.new :firefox
b.goto 'http://mistones.dev/hdz-granite-dallas/review'
b.text_field(:name, 'title').set('Great stock and fast service')
b.text_field(:name, 'comment').set('
        Both my husband and I are pretty happy with the job the
        guys at HDZ Granite have done in our kitchen and our
        master bath. Fair price, helpful, informative and on time.
')
b.button(:value, 'send').click

Bastante claro, ¿no? Le decimos a Watir que abra una URL. Que dentro del documento HTML de esa URL rellene los campos, cuyos atributos name son ‘title’ y ‘comment’, con los datos que le pasamos. Y que a continuación pulse el botón cuyo atributo value es ‘send’.

Nos falta añadir la evaluación. En nuestro caso, vamos a evaluar si existe cierto contenido en el documento HTML, contenido que sabemos que sólo existe en la página posterior a un envío correcto.


if b.text.include? 'Your Review has been Published'
        puts 'Test passed. Test review successful.'
else
        puts 'Test failed. Test review was not successful.'
end

Con ésto ya tenemos un test completo. Podemos probarlo llamándolo:


ruby test_review_form.rb

A continuación, Watir abre el navegador instanciado en el test y ejecuta los pasos indicados. Cuando termina, devuelve los mensajes de ‘passed’ o ‘failed’.

Una vez que cuentas con este tipo de tests, dependiendo de tus gustos, filosofía, metodología, estilo, etc. puedes automatizarlos con herramientas de integración continua, o crearte tu propio proceso de comprobación, o sencillamente correrlos cada cierto tiempo para asegurarte de que las cosas siguen funcionando.

Git: ver el log, buscar en el log

23 de agosto, 2011 - por | | Desarrollo, Tips

Una buena búsqueda te puede ayudar mucho. También a sobrevivir.

Cuando llevas un tiempo trabajando en un repositorio con Git, empiezas a tener la necesidad de revisar el log de lo que ha ido pasando. Algunas de las acciones más típicas con las que te vas a encontrar, son las siguientes.

Ver lo que ha cambiado en cada commit


git log -p

Ver los ficheros que han cambiado en cada commit


git log --stat

Ver el listado de todos los commits con sus ramas


git log --pretty=oneline --abbrev-commit --graph --decorate

Ésto te devuelve un listado de los commits con sus títulos abreviados, en una sola línea y con una representación jerárquica de sus ramas. Puedes verlo en la siguiente captura de uno de nuestros proyectos:

Buscar palabras que aparecen en el título del commit


git log --grep="tu búsqueda"

Buscar cuándo algo fue añadido o eliminado


git log -S "tu búsqueda"

Filtrar por fechas recientes con MySQL sobre Codeigniter

12 de agosto, 2011 - por | | Desarrollo

Nos pierde lo que acaba de suceder. Vivimos más intensamente lo que es reciente.

Hace poco he tenido que desarrollar el clásico grupo de filtros en forma de checkboxes, combos y radio buttons que se van aplicando con cada click que hace el usuario sobre un listado inicial de todos los elementos posibles.

Uno de los filtros tiene el siguiente aspecto:

La forma más fácil de desarrollar este filtro la encontré utilizando la función MySQL DATE_SUB(). Esta función tiene la siguiente sintaxis:


DATE_SUB(date,INTERVAL expr type)

donde date es una fecha cualquiera válida, y INTERVAL el número que quieres sustraer.

Lo que hice fue lo siguiente. A cada una de las opciones del filtro le asigno un valor numérico (31, 7 y 2 respectivamente). Considero date como el día de hoy, es decir, el momento en el que el usuario está aplicando el filtro. Le paso ambos argumentos a la función de MySQL, en la forma en el que Active Record de Codeigniter permite hacer este tipo de cosas:


$where = "upload_ts > DATE_SUB( NOW( ) , INTERVAL " . $days . " DAY)";
$this->db->where($where, null, false);

Instalar SSH2 para PHP 5.3 en CentOS

10 de agosto, 2011 - por | 1 comentario | Desarrollo, Sistemas

En el proceso de instalación de SSH2 para PHP 5.3 sobre CentOS hay un primer paso que sigue funcionando igual de bien que anteriormente:


yum install gcc php53-devel libssh2 libssh2-devel

Sin embargo, PHP 5.3 sobre CentOS aún no ha incorporado el paquete correspondiente para:


php53-pear

necesario para manejar la instalación de la extensión SSH2 mediante PECL. Es un bug ya apuntado en el Bugzilla de Redhat, pero que aún está pendiente de resolución.

Hay dos métodos principales para resolver este problema. Uno que consiste en utilizar el repositorio IUS, que ofrece paquetes php53 y extensiones más actualizados, junto con un php53-pear. Si te decides por este método, este post de Eric London te explica los pasos principales (en inglés).

El segundo método consiste en conservar el paquete tradicional php-pear y forzar su actualización mediante los siguientes comandos:


pear upgrade --force Console_Getopt
pear upgrade --force pear
pear upgrade-all

Una vez que tienes instalados los paquetes mencionados, ya puedes instalar la extensión SSH2:


pecl install -f ssh2

Una vez que esté instalada, verás que al final del proceso de instalación te indica como siempre la línea que debes añadir al fichero php.ini:


extension=ssh2.so

Reinicias tu servidor HTTP y compruebas que la extensión está cargada y funcionando:


php -m | grep ssh2

WordPress como CMS: identificar subpáginas

9 de agosto, 2011 - por | | Desarrollo

Si te has animado a utilizar WordPress como CMS, un poquito más allá de su foco original de funcionar como un blog, la gestión de las páginas pronto se va a convertir en uno de tus temas habituales de desarrollo.

Cuando empiezas a montar la estructura de información del sitio, y separas los contenidos por áreas, te encontrarás probablemente con la clásica estructura de árbol, en la que hay unas páginas principales de las que cuelgan otras secundarias. Identificar en qué pagina y subpágina se encuentra el usuario te va a venir bien para muchas cosas, empezando por un menú básico que ayude a navegar con más facilidad.

WordPress cuenta con su propia función para determinar en qué página te encuentras:


is_page($page);

pero no con una para determinar la subpágina. En nuestros proyectos solemos utilizar la siguiente:


/**
 * Returns boolean value for checking if the current page is child
 * of a parent page
 *
 * @param int
 * @return bool
 */
function is_subpage($iID = null)
{
        global $post, $wpdb;
        if ( is_page() AND isset( $post->post_parent ) != 0) {
                $aParent = $wpdb->get_row( $wpdb->prepare(
                    "SELECT ID FROM $wpdb->posts \
                    WHERE ID = %d AND post_type = 'page' LIMIT 1",
                    $post->post_parent
                ) );
                if ( is_int( $iID ) > 0 ) {
                        if ( $aParent->ID == $iID ) {
                                return true;
                        } else {
                                return false;
                        }
                } else {
                        if ( $aParent->ID ) {
                                return true;
                        } else {
                                return false;
                        }
        } else {
                return false;
        }
}

La llamamos desde el fichero:


/wp-includes/functions.php

Utilizar InnoDB en Django

8 de agosto, 2011 - por | | Desarrollo, Tips

Si estás empezando a trabajar con Django y vas a utilizar MySQL, te conviene pararte un momento a mirar si estás utilizando el tipo de almacenamiento que realmente quieres.

Al generar los esquemas, Django no especifica ningún tipo de almacenamiento; sencillamente los genera con el que está establecido en tu servidor de MySQL. Así que si aún no has generado ningún esquema, revisa tu configuración de MySQL. Todas las versiones previas a la 5.5 hacían de MyISAM el almacenamiento por defecto.

La configuración del tipo de almacenamiento la puedes hacer directamente en MySQL, o especificarla en los settings de tu conexión a la base de datos en Django utilizando la opción “init_command”. Por ejemplo, del siguiente modo para establecer InnoDB como el tipo almacenamiento por defecto.


'OPTIONS': {
   'init_command': 'SET storage_engine=INNODB',
}

Si ya cuentas con algunas tablas, y te encuentras con que están con un tipo de almacenamiento distinto al que tu pensabas, te va a tocar modificar las tablas en la forma habitual:


ALTER TABLE tablename ENGINE=INNODB;