Proyecto

General

Perfil

Este documento es una copia de:

https://gong.org.es/projects/gor/repository/show/trunk/testing/gor/README

El nuevo sistema de testing que propone este documento está en revisión. Su versión definitiva se cerrará una vez se pruebe en la liberación de nuevas versiones

Testing en GONG

Ejecutar los test de GONG

El testing de GONG se basa actualmente en el Plugin de FireFox Selenium IDE.

http://www.seleniumhq.org/docs/02_selenium_ide.jsp

La versión actual sobre la que trabaja es:

  • Selenium 2.9.1
  • Firefox 51.0.1 (64-bit)

Ademas es necesario (o podria ser necesario) instalar flowcontrol un plugin para Selenium que tambien se instala como complemento del Firefox. Ver:

Para descargar los test:

svn co https://gong.org.es/svn/gong/trunk/testing/gor

Para correr todos los tests abrir la test suite:

todos_los_tests

El servidor de desarrollo de test es:

http://test.desarrollo.gong.org.es/

Este servidor de testing, o cualquier otra instancia que se quiera utilizar para realizar los tests, debe tener:

  • Instalado y activado el plugin de testing.
  • Instalado el plugin de formación

Estructura de los tests

  • En el raíz se encuentra los test_suite
  • En los directorios se encuentran los test_case, agrupados en:
    • administración
    • agente
    • proyecto_configuracion
    • proyecto_formulacion
    • proyecto_ejecucion
    • herramientas
    • nuevas agrupaciones que surjan

Todos los test_suite se agrupan, finalmente, en un solo test_suite

todos_los_tests

Dado que Selnium IDE no permite crear "test_suites de test_suites", a través del script:

script_unir_todos_los_test.sh

se re-genera la suite todos_los_tests (que incluye todas las test_suites) para facilitar su uso y no tener que abrir una a una todas las test-suites.

Posibles ajustes de Selenium

En las opciones generales de selenium se puede:

  • Bajar la velocidad de ejecución de "fast" a "slow". Se recomienda bajar la velocidad "un poco" (¿Ambiguo?) respecto al "fast".
  • Bajar el timeout de espera de todas las ordenes de Selenium (por ejemplo todas las ordenes "wait"), en las opciones > generales del plugin. Dado que el timeout esta en 30 seg (30000 ms), algunos tests tardan demasiado en fallar. Bajarlo (dependiendo del contexto de las pruebas) es recomendable.

Nota: Hay que tener en cuenta que cualquier accion que se entienda que va a tardar tiempo, vendrá precedida de un cambio de timeout (ver por ejemplo herramientas/crear_proyecto)

Posibilidades para ejecutar los tests.

Para ejecutar los tests, se puede ir uno a uno, o se puede ejecutar el test general que aglutina a todos los test.

En el caso de ejecutar el test se puede seguir el siguiente orden:

  1. Ejecutar el test que aglutina a todos los test todos_los_tests.
  2. Si da fallos:
    1. Acudir directamente a ejecutar los test individuales que ha/n fallado.
    2. Introducir "breaks"a mano antes de las acciones "cerrar_transaccion" que se quiera observar y trazar lo que ha sucedido.
    3. Introducir "breaks" en todas las acciones "cerrar_transaccion".

La ultima posiblidad implia introducir un comando break en:

# En herramientas/cerrar_transaccion
# Esto no es necesario hacerlo editando el archivo, se puede hacer visualmente desde el plugin
<!--En este punto se puede introducir un comando break para debugging general-->
<tr>
        <td>break</td>
        <td></td>
        <td></td>
</tr>
<!--Antes de este test_case necesitamos ejecutar entrada para asegurar que estamos dentro-->
<tr>
        <td>open</td>
        <td>/testing/administracion/testing/cerrar_transaccion</td>
        <td></td>
</tr>

El problema de esta opción es que implica ir dando a continuar manualmente antes y después de todos los tests (cerrar_transaccion se encuentra antes y después de cada test)

Posibles problemas con las transacciones.

Dado que cada test abre y cierra transacciones, podría darse el caso de inconsistencia en las transacciones dando un error de la bbdd de tipo:

Mysql2::Error: SAVEPOINT active_record_1 does not exist: ROLLBACK TO SAVEPOINT active_record_1

Esto se puede solucionar ejecutando desde el menú de testing la opción de "resetear" (ver el apartado sobre las opciones del plugin de testing)

Importante: Debido a este misma situación de que los tests abren y cierran transacciones, contra una misma instancia no puede lanzar tests mas de un usuario.

Servidor de testing.

La instancia especifica para testing se encuentra en:

http://test.desarrollo.gong.org.es/

Los "test_case" (a excepción del test_case "Entrada") no tienen URL Base, y todas las URLs que se utilizan para la navegación son relativas. Esto permite modificar la dirección de base a los que se dirigen los tests. Para testear contra otra instancia de GONG solamente es necesario cambiar la URL del fichero de test_case herramientas/entrada, en la linea:

<link rel="selenium.base" href="http://test.desarrollo.gong.org.es/" />

Situación actual del testing de GONG

El sistema de testing esta en revisión actualmente y podríamos cambiarlo en función de los próximos pasos.

En la forma actual que hemos elegido, basada en Seleniumn (siguiendo la primera estructura que ya teníamos), necesitamos cumplir dos objetivos:

  • Que cubra unos mínimos de testing ante todo los nuevos cambios que van a darse en GONG (upgrade de javascript, ruby y rails), y los cambios que se dan habitualmente en cada una de las nuevas versiones.
  • Implantar sobre este formato basado en Selenium. un sistema de actualización de tests con dada nueva versión. De esta forma se asociarán nuevos tests a cada nueva funcionalidad, mejora, o error, incluidas en la versión.

En este primer trimestre del 2017 nos hemos dedicado solamente a actualizar los tests, y a introducir un nuevo plugin (testing) para facilitar ciertos procesos. A partir de este momento implantaremos antes de cada versión el desarrollo de los nuevos tests, y en función de la experiencia que tengamos modificaremos la plataforma o estructura propuesta.

Como se explicará posteriormente en la numeración de los tests, los tests iniciales son una actualización de los tests anteriores a esta fecha, y no tienen ninguna referencia a los tickets (su numeración es de tipo 254_0000_*). Dado que existe un desfase en el testing respecto al desarrollo funcional, este tipo de test (XXX_0000_*) se irán desarrollando periodicamente para intentar cubrir esta falta. Se llevará un listado de los mismos aqui:

Listado de tests generales (no referidos a tickets)

Desarrollo de tests en cada versión.

Como se ha comentado, vamos a implantar, sobre este formato basado en Selenium, un sistema de actualización de tests con dada nueva versión. De esta forma antes de liberar cada versión se reservarán unas jornadas a:

  1. Actualizar todos los tests que fuesen necesarios.
  2. Crear nuevos tests para (cada uno de) los nuevos tickets.

Desarrollo de tests

Plugin de testing.

Los tests se apoyaran en el plugin de testing. El plugin tiene varias acciones con la idea de facilitar el proceso de testing:

  • Abrir transacción. Ruta:
    /testing/administracion/testing/abrir_transaccion
    
  • Cerrar transacción. Ruta
    /testing/administracion/testing/cerrar_transaccion
    
  • Limpiar GONG. Borra los datos de las tablas y carga el seeds inicia de GONG. No hace "drop" de las BBDD, con lo que resulta mas rápido. Ruta:
    /testing/administracion/testing/limpiar
    
  • Resetear la BBDD. Hace drop de las tablas y restaura el seeds inicial. Ruta:
    /testing/administracion/testing/borrar
    
  • Cargar un proyecto en configurado, y formulado (basado en el plugin de formación). Utiliza el plugin de formación, cargando un proyecto, configurándolo y formulándolo.
    /testing/administracion/testing/crear_proyecto
    

Todas estas acciones se puede invocar desde el menú de testing en configuración del sistema:

/testing/administracion/testing

El plugin se apoya en la gema DatabaseCleaner para los procesos de abrir y cerrar transacciones y:

https://github.com/DatabaseCleaner/database_cleaner

Contexto inicial.

Todos los tests partirán de un contexto, en el cual:

  • Se ha limpiado la BBDD. Se ha ejecutado la acción limpiar descrita en el anterior apartado
  • Se ha cargado el seeds. Se ha ejecutado la acción limpiar descrita en el anterior apartado. Concretamente, la acción limpiar ejecuta:
    DatabaseCleaner.clean_with :truncation # Borra los datos de las BBDD
    rake db:seeds # Carga los datos iniciales de sistema
    
  • Se ha cargado un proyecto. Se ha ejecutado la acción, crear_proyecto descrita en el anterior apartado
    Concretamente, la acción crear_proyecto ejecuta:
    rake formacion:genera['1','3'] # Carga un proyecto en estado de formulación
    

Estas aciones se encuentra recogidas dentro del test_suite:

000_0000_cargar_estado_inicial

Este test_suite, no es necesario ejecutarlo antes de cada test dado que consumen bastante tiempo. Si se incluira en la test_suite final de ejecucion conjunta de todos los test.

Para cada nuevo test solo se invocara las acciones abrir_transaccion y cerrar_transaccion. Esto hará que todos los cambios que se ejecuten en el test se borren al acabar dicho test, o mientras se esta desarrollando el test, si este da fallos.

En el futuro, si se considerase necesarios crear contexto específicos para situaciones y escenarios complejos, se puede recurrir a crear nuevas acciones del plugin que creen contextos específicos complejos para la ejecución de tests.

Denominación de los tests.

Los test_suites se encuentran en el raíz del directorio de testing. El nombre de los test_suites responderá al siguiente formato:

XXX_YYYY_NombreDelTest

  • XXX: Numero general de la versión de GONG que estamos testeando.
  • YYYY: Numero del ticket al que va asociado.
    • Los tests XXX_0000 serán tests que no están asociados a ninguna petición. Por ejemplo todos los tests iniciales que hemos desarrollado no responden a ninguna petición y tienen esta numeración 0000
  • NombreDelTest. Cualquier nombre explicativo sencillo.

Los test_case no tendrán una numeración, y se encontrarán en la carpeta especifica de cada grupo de funcionalidades. Si fuese necesario se abrirán nuevas carpetas para test_case.

Dentro de cada test_suite se nombrarán los test_case de la siguiente forma:

Carpeta > Nombre del test case

Del mismo modo, y tal y como se explica en el template de referencia para los nuevos tests, el primer case de entrada al sistema se le pondra el nombre del propio test_suite (XXX_YYYY_NombreDelTest). Esto facilita la visualizacion de los test cuando se agrupan en un solo test (todos_los_tests)

Creación de nuevos tests.

Para cada nueva funcionalidad se creará un nuevo test_suite basado en el test_suite template. La test_suite se guardará en el raiz del sistema de tests, y los test_case que se desarrollen para dicha test_suite se encontrarán en las carpeta especifica de test_case correspondiente (agente, administración,..etc).

Cada test (test_suite) será "atómico", es decir, que no dependa de otros test. Ademas dejará la instancia sobre la que se desarrolla en el mismo punto de partida, abriendo una transaccion al iniciar el test, y cerrandola al acabar, produciendo el "rollback" de todas las acciones en la BBDD. Para esto el template se apoya en varios test_case:

  1. Antes del test_case, o de los test_case se ejecutará varios test_case que garantizan que:
    1. Estamos loggeados.
      • test_case: herramientas/entrada
    2. Cerramos transaccion abierta, evitando fallos de posibles transacción abiertas pendientes que darían errores de consistencia.
      • test_case: herramientas/cerrar_transaccion
    3. Estamos loggeados. Nos volvemos a loggear (si fuese preciso)
      • test_case: herramientas/entrada
    4. Abrimos transaccion, para poder cerrarla y borrar los datos al final del test.
      • test_case: herramientas/abrir_transaccion
  2. Realizamos nuestro test, creando uno o varios test_case, y/o apoyándonos en nuevos test_case.
  3. Finalizamos cerrando la transacción
    1. Estamos loggeados.
      • test_case: herramientas/entrada
    2. Cerramos transaccion abierta, borrando los datos.
      • test_case: herramientas/cerrar_transaccion

Para cada comportamiento que queramos testear, crearemos inicialmente un solo nuevo test_case, que introduciremos en la secuencia de test_case que tiene template que acabamos de describir. Aparte de nuestro test_case podemos crear o reutilizar otros test_case en las siguientes circunstancias:

  • Que necesitemos crear un contexto, reutilizando test_case que ya estan desarrollados.
  • Que entendamos que nuestra acción lleva implicita otras acciones que queramos dividir para su reutilización en otras circunstancias.
  • Aparte de estos casos, tambien se puede dar el caso que decidamos dividir test_case ya realizados, bajo estos criterios de reutilización de codigo.

Para grabar un nuevo test con Selenium IDE ver el manual, o chequear la siguiente guia:

https://gong.org.es/projects/gor/wiki/Test_comportamiento_(Uso_de_Selenium)

Problemas para restaurar la situación inicial.

El esquema que acabamos de describir de abrir y cerrar transacciones, no consigue restaurar completamente la situación inicial, debido a que los IDs autoincrementales internos de las BBDD no vuelven a su estado inicial.

Esto no debería ser un problema si los identificadores html que hemos puesto a los elementos para localizarlos en el sistema de testing, están basados en variables secuenciales.

El problema es que existen ocasiones en las que hemos utilizado para los identificadores de los elementos en las vistas los IDs de las entidades de la BBDD. En este caso adoptaremos dos soluciones:

  • Refactorizar el código de la vista para utilizar un iterador como en otros listados.
  • Localizar los elementos a través de "xpath" en vez del "identificador"

El servidor de test

El script /home/sramos/scripts/actualiza_test en el servidor de test actualiza el gong y sus plugins en /srv/test/.

Los plugins utilizados por esta instancia son los en /srv/test/gor_plugins.

La instancia 'test.desarrollo' (/etc/apache2/sites-available/test.desarrollo) es independiente de las otras instancias ('formacion', 'desarrollo', …). salvo por la gemset de rvm.

El modulo de apache 'passenger' (/etc/apache2/mods-enabled/passenger.load) apunta a la gemset en /usr/local/rvm/gems/ruby-1.9.3-p551 para toda las instancias de apache.