Automatización de pruebas funcionales con Selenium en Yii usando Netbeans

El título de esta entrada es un poco largo, pero intentaré de explicarles de una manera sencilla como podemos hacer pruebas funcionales en nuestras aplicaciones hechas con el framework de PHP Yii, usando Selenium y Netbeans. Para quienes no conocen las pruebas funcionales, son aquellas para comprobar la correcta ejecución de cada una de las funcionalidades del sistema, muchas veces hacemos este proceso manualmente: entrando al sitio, escribiendo a mano (o usando un plugin del navegador) cada campo, haciendo clic en los botones y así sucesivamente. Pero cuando el sistema se hace muy grande o estamos en agregando funcionalidades, se puede perder mucho tiempo en realizar este proceso, si se deja para el final (como en las metodologías antiguas) puede ser muy tarde y si se omite tendremos un software con potenciales fallas.
La idea es automatizar este proceso, para que con un solo clic se ejecuten muchas pruebas y asegurarnos el correcto funcionamiento del programa a lo largo del desarrollo y mantenimiento del mismo.

Configuración en Netbeans

Para esta guía deben tener ya instalado y configurado los siguientes programas: Netbeans, PHP Unit, un programa hecho con Yii framework, Selenium Server, Firefox (Debe ser igual para otro navegador pero no lo probé), Linux (No sé si este proceso es igual para Windows).

Primero lo que vamos a hacer es instalar un plugin de Netbeans para manipular el servidor de Selenium desde el IDE, este paso es opcional pero me parece mas fácil iniciarlo / detenerlo con un clic que a través de comandos. Para ello vamos a:

  1. Entrar en Netbeans.
  2. Luego en el menú “Tools -> Plugins -> Available Plugins“.
  3. Allí buscamos el que tenga el nombre de “Selenium Module for PHP” le damos clic en Install.
  4. Una vez finalizada la instalación, en la pestaña de Servicios en la parte de Servidores tendremos el de Selenium.
Servidor Selenium

Servidor Selenium

Antes de iniciar las pruebas, debemos arrancar el servidor de Selenium con clic derecho y luego en “Start”. Luego procedemos a configurar el proyecto actual (el realizado en Yii) para indicar a Netbeans donde se encuentran las pruebas y PHP Unit:

  1. Hacemos click derecho en el proyecto y luego en “Properties”.
  2. En la sección “Sources” existe una caja llamada “Test Folder”, en ella vamos a colocar la ruta absoluta a la carpeta /protected/tests del proyecto (en caso de no funcionar, entonces a /protected/tests/unit).
  3. Luego en la misma ventana, cambiamos la sección “PHPUnit” y activamos donde dice “Use Bootstrap” donde rellenamos la caja de texto a la ruta absoluta de /protected/tests/bootstrap.php
  4. Luego activamos la opción “Use XML Configuration” y rellenamos en la caja la ruta absoluta de /protected/tests/phpunit.xml.

Con esto ya esta configurado Netbeans, sin embargo, en mi caso no funcionó de una vez hasta hacer unos pequeños ajustes:

  1. En mi caso no quería detectar al navegador Firefox, para hacerlo funcionar en el archivo de configuración (phpunit.xml) tuve que eliminar todo el contenido dentro de las etiquetas <selenium></selenium> dejándolas como las acabo de escribir.
  2. En el archivo WebTestCase.php,en la función setUp() necesité colocar $this->setBrowser(‘*firefox’); para indicar el navegador por defecto.
  3. Como estaba usando Bootstrap para el frontend, Selenium debe esperar un poco hasta que algunos eventos de Javascript terminen de mejorar la apariencia visual, para ello en el archivo /protected/config/main.php se agrega enla sección de preload lo siguiente (asumiendo la carga de log como se encuentra por defecto):
    'preload' => array('log',
        php_sapi_name() !== 'cli' ? 'bootstrap' : '',
    ),
  4. Listo, ya con presionar Alt + F6 empezará a ejecutar todas las pruebas, si solo quieren para la clase actual deben presionar Shift + F6.

Consejos para las pruebas

A continuación les doy unos consejos y extractos de código, pues al principio me costó encontrar como realizar las siguientes tareas en Selenium.

  • Iniciar sesión en cada prueba: para ello deben crear en WebTestCase.php (la clase principal para las pruebas) un método para el login que comience con _ (piso), pues éstos no se ejecutarán en las pruebas, aquí mi les dejo código y luego en cada prueba hacen un $this->_login() donde requieran identificarse.
    protected function _login() {
     $this->windowMaximize();
     $this->open("site/login");
     $this->type("LoginForm_username", "skatox"); //Donde LoginForm_username es el id del usuario
     $this->type("LoginForm_password", "contrasena");
     $this->click("LoginForm_rememberMe"); //Permite recordar y no estar autenticando cada rato
     $this->click("name=yt0");
     $this->waitForPageToLoad(self::PAGE_LOAD_WAIT_TIME); //constante que declaré para esperar un tiempo
    }
  • Interactuar con la ventana de confirmación al eliminar un elemento del grid: En este caso se me complicó porque se debe interactuar con una ventana de javascript, el siguiente código también está en WebTestCase.php porque lo utilizo a lo largo de todas las pruebas, los parámetros son: $confirmMsg que es el mensaje de confirmación que aparece en la ventana y $nonFoundMsg, mensaje de cuando se ha borrado el elemento.
    protected function _testDelete($confirmMsg, $nonFoundMsg){
     sleep(self::WAIT_JS_TIME); //tiempo para esperar la ventana de javascript
     $this->chooseCancelOnNextConfirmation(); //Selecciona el boton cancelar para probar este paso
     $this->click($this->firstDeleteXpath); //Hace clic en el boton de eliminar del grid (Xpath)
     $this->assertConfirmationPresent($confirmMsg); //Se asegura que esta bien el mensaje
     $this->getConfirmation();
     sleep(self::WAIT_JS_TIME);
     $this->chooseOkOnNextConfirmation(); //Escoge aceptar
     $this->click($this->firstDeleteXpath);
     $this->assertConfirmationPresent($confirmMsg);
     $this->getConfirmation();
     $this->waitForTextPresent($nonFoundMsg); //Espera que no hayan resultados porque los borró
    }

Ya con estos pasos pueden empezar a realizar las pruebas funcionales de forma automática, si quieren conocer como se vé, les dejo un vídeo de unas pruebas de un módulo de una aplicación que estoy realizando:

 

15 comentarios

  1. Me sorprende no ver ningún comentario, está bastante bien el inicio a Selenium.

    Se me plantea una duda. ¿Se pueden ejecutar estas pruebas automáticamente a través de un comando que ejecute ese test, supongo que a través de linea de comandos?

    Tras realizar las pruebas, vuelves a un estado inicial de la base de datos para no “manchar” tu base de datos de desarrollo o producción?

    En un servidor de desarrollo o producción, donde normalmente no tenemos si quiera ventanas de navegación, como podemos ejecutar las pruebas?

    Gracias!

  2. Gracias, opino lo mismo. Ya la gente no comenta sino que te contacta por redes sociales. Aquí van mis respuestas (a las que conozco)

    Se pueden ejecutar las pruebas utilizando el comando phpunit, de esta manera puedes crear scripts para lanzar las pruebas desde un comando.

    Si, es posible mantener el estado de las base de datos, con Yii puedes hacerlo usando los fixtures para no tocar la BD. O puedes usar una BD para puras pruebas.

    La ultima si no śe si es posible hacerla.

  3. Bueno, pues seré yo quién comente entonces… 😀

    Respecto a realizar pruebas en desarrollo en un servidor donde solo tengamos un Linux sin entornos X, se puede llegar a ejecutar sin abrir ventanas gracias a xvfb, pero eso no impide que tengas que tener el propio navegador, veáse firefox, ya que selenium no es un navegador en si mismo, sino un driver capaz de emular las acciones. He hecho los deberes y he estado mirando… 😉

    Buen blog, quizás un día de estos, cuando sea capaz de finalizar la implementación de pruebas, me decido a escribir una entrada en mi blog 😉

  4. Que mas pues Skatox, tengo ciertas dudas sobre la instalación de esto:
    1.Se tiene que tener instalado el behat o solo es con selenium?
    2. Hay que instalar el composer?
    3.Hay alguna configuración especial para que funcione con el yii?, por ejemplo en el archivo config/main

    Muchas gracias….. y espero tu pronta respuesta…

  5. skatox lo que pasa es que instale todo, genero la prueba le doy run y me genera un error de dispachedEvent event, al parecer al hacer click, quito la lineas de click, submit y la prueba se realiza satisfactoriamente, me podris ayudar, tengo netbeans 7.3.1 corre el server selenium bn, pero no se poruqe genera error en esos eventos…

  6. Saludos Skatos, tengo una aplicacion en yii pero no estoy usando bootstrap
    la duda es que deben contener los archivos bootstrap.php y phpunit.xml que van dentro de la carpeta /protected/tests

  7. Saludos, pues el archivo bootstrap.php posee información de como arrancar el sitio de pruebas, indica la carpeta de Yii, la configuración de pruebas entre otros. phpunit.xml lo he dejado como viene por defecto.

  8. Saludos Skatox, stoy realizando unas pruebas todo va bien hasta que incluyo alguna función que realice un click como click, clickAndWait, click(“//a[@href=”]”)

    probé con win7, win8, netbeans 7.4 y 7.3

    aun no logro solucionar el problema

    el testResult de netbeans me arroja lo siguiente

    testShow::testShow()

    Invalid response while accessing the Selenium Server at ‘http://localhost:4444/selenium-server/driver/': ERROR: Command execution failure. Please search the user group at https://groups.google.com/forum/#!forum/selenium-users for error details from the log window. The error message is: Argument 1 of EventTarget.dispatchEvent does not implement interface Event.

    C:\xampp\htdocs\yii\framework\test\CWebTestCase.php:64

    C:\xampp\htdocs\casa\protected\tests\BancoTest.php:22

    C:\xampp\htdocs\casa\protected\tests\BancoTest.php:22

    Linea 22 de BancoTest —-> $this->clickAndWait(‘name=yt0′);
    Linea 64 de CWebTestCase.php —-> return parent::__call($name,$params);

    De ante mano Gracias

Deja un comentario