miércoles, 3 de diciembre de 2014

MarkLogic - Test Unitarios con Roxy


Test Unitarios con Roxy

La industria del software cada día necesita entregar más prototipos, en menos tiempo con mayor calidad. Pero si nos detenemos a pensar en esto, la primera impresión es que algo estamos haciendo mal o no estamos usando las herramientas correctas para hacerlo. Para no entrar en discusiones, YO voy a decir que siempre podemos encontrar y aprender la manera de hacer algo mucho mejor de lo que actualmente es. 

De acuerdo con lo anterior y en inspiración de mejorar los procesos de desarrollo de aplicaciones realizadas con MarkLogic, he decidido realizar este post sobre como realizar Test Unitarios con Roxy para ayudar a mejorar los procesos de integración, permitiendo encontrar problemas de sintaxis, casting o permisos de manera más rápida y controlada en los servidores de los clientes. Digo servidores de los clientes, porque en nuestros ambientes ya deberíamos estar haciendo esto. 

Ahora que ya estamos en contexto, para poder entender este post vas a necesitar saber sobre:

  1. MarkLogic
  2. Roxy - Más info aquí
  3. XQuery

Configurando Roxy


Lo primero que debemos hacer para iniciar es descargar el código de Roxy desde el repositorio. Esto lo pueden realizar con git o descargando el zip desde github. Una vez tengan el código, debemos crear una aplicación desde la linea de comandos usando el siguiente comando:
./ml init app-name --server-version=7 --app-type=rest
Para windows
ml.bat init app-name --server-version=7 --app-type=rest

Con este comando crearemos una aplicación que se llamará "app-name", que correrá en la version 7 de MarkLogic y que será de tipo "rest". Luego de ejecutar este comando debemos ir a modificar el archivo "build.properties" creado por el framework en la carpeta "deploy". Podemos cambiar las configuraciones que deseemos, pero para este ejemplo nos vamos a enfocar en los siguientes cambios:

  • test-content-db=${app-name}-content-test
  • test-modules-db=${app-name}-modules
  • test-port={ PUERTO DISPONIBLE}

con estos cambios ahora solo resta ejecutar el comando para crear los servidores, bases de datos y forests. Para esto ejecutamos los siguientes comandos:
./ml local bootstrap
./ml local restart
./ml local deploy modules
Para windows
ml.bat local bootstrap
ml.bat local restart
ml.bat local deploy modules
después de ejecutar estos comandos estarán creados los servidores y podrán ingresar a http://localhost:{puerto} para ver la aplicación corriendo.

Creando el primer test unitario


Para crear nuestro primer test unitario vamos a necesitar abrir la carpeta "src" que se encuentra en la raíz de Roxy. En esta carpeta encontraremos 4 carpetas más, a continuación una breve explicación de que es cada una:

  1. App: Es la carpeta donde debemos colocar todos nuestros archivos de XQuery que van a ser usados por el REST para tareas de servidor.
  2. Public: Es la carpeta que contiene todo el front-end de la aplicación, imágenes, javascripts, etc.
  3. Roxy: Es la carpeta que contiene todo el código del Framework
  4. Test: Es la carpeta donde están todos los test unitarios y es la que vamos a usar.
La carpeta de Test tiene una carpeta llamada "suites" la cual tiene una carpeta por cada uno de los tests que deseemos correr en la aplicación, por tanto vamos a crear una carpeta llamada "Mi Primer Test" dentro de la carpeta "suites" (/src/test/suites/). Dentro de esa carpeta vamos a crear un archivo llamado "primer-test.xqy", el cual tendrá el siguiente código:

xquery version "1.0-ml";
import module namespace p = "http://yuxipacific.com/models/project" at "/app/models/project.xqy";
p:create("/project/test.xml","Test 1", "fabian@hotmail.com", "document.docx",("test","unit"))
;
import module namespace test="http://marklogic.com/roxy/test-helper" at "/test/test-helper.xqy";
test:assert-exists(fn:doc("/project/test.xml")/name[.= 'Test 1']),
test:assert-exists(fn:doc("/project/test.xml")/users/user[.= 'fabian@hotmail.com']),
test:assert-exists(fn:doc("/project/test.xml")/files/file[.= 'document.docx']),
test:assert-exists(fn:doc("/project/test.xml")/tags/tag[.= 'test']),
test:assert-exists(fn:doc("/project/test.xml")/tags/tag[.= 'unit'])

Como pueden ver en el código anterior tenemos un script de XQuery que esta ejecutando dos transacciones. En MarkLogic cuando se encuentra un ";", hace referencia a separación de transacciones, por lo que el anterior código ejecutará la primera parte en una transacción y la siguiente en una transacción posterior a la primera. Lo que nos permite poder ver en la Base de Datos los cambios realizados en la primera transacción.

Ahora bien, el código de la primera transacción esta importando un modulo llamado project, el cual posteriormente es usado para llamar la función "create" a la cual se le pasan unos parámetros para su correcta ejecución. En la segunda transacción se importa el modulo de test de Roxy y se realizan unos asserts que verificarán sí lo que se le pase como parámetro existe o no. Para este ejemplo, la primera transacción ha creado un documento en la Base de Datos, que en la segunda transacción verificamos haya sido creado y contenta cada uno de los elementos que deben haber quedado guardados en el XML.

Con esto ya hemos creado nuestro primer Test Unitario que validará que nuestra función de crear proyectos funcione sin problemas.

Ejecutando las pruebas unitarias


Para poder visualizar la interfaz de Test Unitarios debemos dirigirnos a nuestro entorno con el puerto que definimos anteriormente para el test-port en la sección de Configurando Roxy, la dirección quedaría así "http://localhost:{puerto}/test".  Cuando vayamos a esta dirección debemos encontrar algo como esto.



En esta pantalla podemos seleccionar de la parte derecha los Tests que deseamos ejecutar, podemos seleccionar todos o solo nuestro Test. Luego en la parte inferior o en la parte derecha encontrarán un botón "Run Tests", si presionan ese botón el sistema ejecutará todos los test seleccionados y retornará un success sí todo se ejecutó correctamente, de lo contrarió informará cual fue el error. 

Con esto ya habrán realizado su primer Test Unitario con Roxy, ya pueden jugar con los diferentes tipos de assert que Roxy provee. Para más información sobre los diferentes tipos de Test Unitarios permitidos presionar Aquí 

Conclusión


No importa el tipo de metodología que estemos siguiendo para la creación de nuestras aplicaciones, siempre va ser útil tener procesos automáticos que nos ayuden a validar que cada integración que realicemos no esta dañando nada de nuestro código antiguo y mucho más prevenir que esos errores lleguen a nuestro proceso de QA. Esta simple tarea mejorará nuestros tiempos de entrega y hará que nuestros ciclos de desarrollo se demoren menos y tengamos menor cantidad de errores. 

Espero este post les ayude a que sus procesos sean mucho más ágiles, con mayor cantidad de funciones y mucho más cortos. Recuerden comentar en caso de que tengan preguntas y si no las tienen, igualmente comenten que es buenos saber sus opiniones. Hasta la próxima!.

2 comentarios:

  1. Small recommendation: use `ml new` instead of `ml init`. That does a few extra things, particularly for app-type rest..

    ResponderBorrar
  2. Thanks for the comment Geert. It's good to see that you take the time to read my post.

    ResponderBorrar