Monday 18 February 2013

Talend Subjobs: Passing Full Context to tRunJob

Talend is an open source software platform that provides data integration, data management, enterprise application integration and big data software and solutions.

As an open source solution, the platform offers the fully free of charge Talend Open Studio, which is a set of open source products for developing, testing, deploying and administrating data management and application integration projects; all of these delivered through an easy-to-use, Eclipse-based graphical environment that provides a comfortable workbench for developers.

I started using Talend as part of some integration projects I was involved with. It was really worth it to explore the tool and I found it really quick to learn; the palette of components provided allows compatibility with a big number of systems and technologies, such as Oracle, Salesforce, Web Services, XML, etc. And apart from all that, Talend generates Java code, so it is very easy to understand and maintain.

But I found an aspect of Talend that, from my point of view, was not very well explained or easy to understand; and it is with regards to the Contexts and how they are passed when using tRunJob components.

Let's have a look at the following example Talend job in order to have a picture of the problem:

Context Group to be used for the Job

The Context Group that will be used for our example job defines two variables, one for the parent job and another one for the child job; it also defines two environments, Test and Dev, as seen on the next image:


This will allow the sample job to be run in different environments, having different parameter configurations.

Simple Talend job that calls a tRunJob component as a child job

This parent job starts by reading a dummy file, it then runs a tJavaRow component to print the value of the Context it receives and it finally passes the Context to a tRunJob component, that will be responsible for calling the child job.


The next image shows the Context variables that are being used for the parent job; in this case there is only one variable: context.parent
 

In order to view what the value of the context.parent variable is in the parent job, the tJavaRow component will print its value, so the code for this component is as follows:

Finally, the tRunJob component performs a call to a child job where the Context variables will be checked again. The configuration of this component is shown next:



















Simple Talend job that represents the child job

The child job will do another dummy reading of a file and another print of Context variables, its design is


Where the Java code to print the value of the Context variables is:

And the Context configuration for the child job will also consist of just one variable: context.child


Several executions are possible

With this configuration, there are several execution options, and at this point is where the tRunJob configuration dialog becomes a bit confusing:
- On the one hand, the "Context" drop-down menu in the dialog specifies the context that will be passed to the child job

- But on the other hand, the "Transmit whole context" check box suggests that the context used in the parent job will be used in the child job

Under these circumstances, two different executions can be run to analyse what is really happening; these are, running the parent job with the Test context environment and running it with the Dev context environment:

Running the parent job under Dev environment

If you click on the Run tab, you can choose from a drop-down menu the different environments you can use to run your job, in this execution Dev will de used:

The result after clicking on the Run button is:

According to the log printed after this execution, the context has been passed as expected, because the parent job was run with the Dev context, and the child job as well. But let's see what happens with the next execution:

Running the parent job under Test environment

If you click on the Run tab, you can choose Test for this second execution:



The result of the execution after clicking on the Run button is:

As you can see, even if the parent job is using the Test context environment, the child job is using the Dev context, so it looks like the "Transmit whole context" check box option in the tRunJob configuration has been ignored by this execution, and the parent did not pass its context to the child job, so it had to use the Dev context, as specified in the "Context" option in the tRunJob configuration.

It looks like the parent job has no control over the context that is passed to the child job, and this is what I was after, being able to decide, from the parent job, what contexts are passed to the children. But the problem I had is that I misunderstood the meaning of the configuration options for the tRunJob component.

How to resolve this misunderstanding

In order for you to be able to pass the context used in the parent to the children, the context for the parent job must hold all the variables required in the child job. So the sample parent job should be using the following Context configuration:


Given this configuration, the parent job holds all of the context variables that are going to be used by the child job. In this case it is only one variable: context.child, and its value will be set from the parent job; so the context variables that will be passed to the child job are previously set by the context environment used by the parent job, Test or Dev.

The executions after changing the Context settings for the parent job are as follows:

- Using the Dev environment in the parent


- Using the Test environment in the parent

In this situation, the "Transmit whole context" option from the tRunJob configuration dialog makes more sense, and it is compatible with the "Context" option in the same dialog:

- All the context variables from the parent job will be passed to the child job, because this is what the "Transmit whole context" option means

- If the child object requires a context variable that has not been passed from the parent object, then the value specified in the "Context" option will be used for the value of that context variable

Tuesday 5 February 2013

Pruebas Automatizadas para aplicaciones DOJO con Selenium WebDriver (Español)

This information in English:
Uno de los principios de las Metodologías Ágiles de desarrollo software es el TDD -Test Driven Development o desarrollo guiado mediante pruebas-, que permite a los desarrolladores tener un mayor control sobre el comportamiento de su código.

La fase de pruebas de tu código ya no representa una pequeña parte de tu proyecto, sino que debe pasar a ser una manera rápida y eficiente de comprobar el código a través de los tests automatizados; al mismo tiempo que facilite el mantenimiento del código en futuras actualizaciones del proyecto. Por eso es necesario incluir el tiempo de pruebas en la planificación del alcance de tus proyectos.

Selenium es un projecto que sirve de gran ayuda a la hora de efectuar pruebas automatizadas de tus páginas o aplicaciones Web; consiste en un conjunto de herramientas software, proporcionando cada una una solución diferente para automatizar tus pruebas.

Selenium te puede ayudar a probar tus aplicaciones Web, del mismo modo que yo lo encontré muy útil para efectuar pruebas automatizadas de mis aplicaciones DOJO.

La versión más reciente de Selenium es Selenium WebDriver, que es el fruto de la unión de dos projectos, Selenium RC y WebDriver, con el fin de que ambas soluciones interactuaran mejor entre sí; todas las referencias a Selenium en este artículo se refieren a la versión Selenium WebDriver o Selenium 2.

Selenium IDE Interface

Primeros Pasos con Selenium

Lo primero que debes hacer para familiarizarte con Selenium es probar la herramienta Selenium IDE, que viene implementado como una extensión de Firefox y permite crear scripts para Selenium. Con Selenium IDE puedes grabar tus interacciones con el explorador, para luego editar y depurar estas pruebas.

La interfaz de Selenium IDE es intuitiva y muy fácil de utilizar nada más instalas el plugin en tu explorador Firefox. Conforme navegas en tu página o aplicación Web, Selenium IDE graba todos los pasos que ejecutas, de modo que puedes guardar tus casos de pruebas (test cases) y agruparlas (suite of tests) para luego reproducir los mismos procesos tantas veces como desees.

Las pruebas creadas con Selenium IDE se pueden reutilizar durante las pruebas de integración de la aplicación Web en el momento de compilar y empaquetar la aplicación los archivos. Hay múltiples opciones, pero en este artículo nos centraremos en usar Selenium WebDriver para ejecutar los test procedentes del IDE de dos formas diferentes:

  • Scripts HTML creados directamente en Selenium IDE como suites de pruebas
  • Pruebas JUnit exportadas por Selenium IDE como clases Java

Selenium WebDriver

Otro módulo de la familia Selenium, a parte del IDE, es Selenium WebDriver, que se puede utilizar para incluir la ejecución automática de pruebas para páginas y aplicaciones Web como parte del proceso de compilado de la propia aplicación.

El ejemplo en el que se basa este artículo es una aplicación DOJO construida con Maven; por lo que se hará uso de las dependencias Maven disponibles para Selenium y los diferentes exploradores que se quieren cubrir como parte de nuestras pruebas.

> Añadir las dependencias para Selenium WebDriver

El siguiente fragmento de código muestra las dependencias Maven necesarias en el fichero pom.xml. Se van a probar los tres exploradores indicados, esto es Firefox, Internet Explorer y Google Chrome.

La versión más actual de Selenium en el momento de escribir este artículo es la 2.26.0.

> Usar las suites de pruebas en HTML de Selenium IDE

El código HTML para ejecutar las suites de prueba se puede obtener de Selenium IDE haciendo: File > Save Test Suite. Una suite de prueba es un conjunto de uno o más casos de pruebas; cuando guardes la suite tendrás que indicar nombres para los diferentes casos de pruebas y para la suite; asegúrate de que el nombre del fichero que representa la suite tiene una extensión de HTML, ya que si no la tiene fallará la ejecución de estas pruebas.

Los fragmentos que se muestran a continuación muestran un ejemplo muy simple de una suite de pruebas con un solo caso de prueba que abre una página de registro de usuario y rellena el formulario.

> Fragmento del fichero que representa la suite:

> Fragmento del caso de prueba:

Los archivos que se generen con Selenium IDE para tus pruebas deberían ser similares a los que se muestran sobre estas líneas.

Una vez creados los ficheros de tu suite de pruebas, pueden ser ejecutados como parte del proceso de compilación, para lo que hace falta incluir más dependencias en el archivo pom.xml para incluir el servidor Jetty y el plugin de Maven para efectuar la llamada a la suite de pruebas. Los siguientes fragmentos de código deben estar presentes en tu fichero pom dentro de la seción build.

> Hay que incluir la dependencia Jetty para que el servidor Jetty arranque la aplicación antes de la fase de pruebas de integración y la pare cuando terminen las pruebas:

> Hay que incluir la dependencia Maven para Selenium, con diferentes ejecuciones del "goal" selenese, una para cada uno de los exploradores que se deseen probar:

No olvides  situar los archivos de tu suite en el directorio correcto y que el fichero de la suite debe tener extensión HTML, si no, el explorador no se cerrará al finalizar las pruebas y el proceso de compilación nunca finalizará, ya que las pruebas no se consideran terminadas.

En este punto ya puedes compilar tu aplicación y ejecutar tu suite de pruebas como parte de las pruebas de integración; simplemente ejecuta el comando Maven: mvn clean install

La compilación de tu aplicación comenzará y verás cómo se ejecutan las pruebas, abriendo los diferentes exploradores para reproducir los casos de pruebas de tu suite de pruebas.

NOTA: Durante las pruebas ejecutadas antes de escribir este artículo, la versión 2.3 del plugin de Selenium para Maven es compatible con Firefox 12, pero no con las versiones posteriores, de manera que si quieres probar el "goal" selenese en Firefox, debes tener instalada la versión 12. Internet Explorer y Google Chrome funcionaban correctamente con sus respectivas últimas versiones.

> Usar las pruebas JUnit exportadas de Selenium IDE como clases Java

El código Java para los casos de prueba se puede obtener haciendo: File > Export Test Case As... > Java / JUnit 4 / WebDriver en Selenium IDE. Se generará una clase Java con anotaciones JUnit para cada uno de los casos de pruebas que exportes desde Selenium IDE. Este código es más una guía de lo que tus pruebas deberían ser, ya que muchas de las instrucciones exportadas no funcionarán como pruebas JUnit; aún así, el código generado es una plantilla muy útil y fácil de mejorar con tu propio código.

La dependencia necesaria para configurar estas pruebas es el plugin de Maven Surefire (a parte de JUnit), como se muestra a continuación:

De acuerdo con la configuración anterior, las clases de prueba para Selenium WebDriver deber estar ubicadas bajo el paquete *.selenium y deben llamarse *Test.java para poder ser ejecutadas como parte de las pruebas de integración JUnit.

Los siguientes fragmentos de código muestran la misma página de pruebas que antes, usando clases de pruebas JUnit para comprobar los tres exploradores: Firefox, Internet Explorer y Google Chrome:

> En este caso, las clases de pruebas para Firefox con compatibles con la última versión del explorador

> Para Internet Explorer, es necesario descargar un driver de Internet Explorer; eligiendo el adecuado a tu versión de Windows (32 o 64 bits), y además hay que expecificar en la clase de prueba que use ese driver

> Para Google Chrome, es necesario descargar el chromedriver adecuado para el sistema operativo en que trabajes, y además indicar en la clase de pruebas que use dicho driver

Ya puedes compilar tu aplicación y ejecutar las pruebas JUnit como parte de tus pruebas de integración; simplemente ejecuta el siguiente comando Maven: mvn clean install. Los resultados de las pruebas se pueden almacenar usando el plugin Maven Surefire Report.

Y hasta aquí mis reflexiones acerca de este tema. Muchas gracias por leer este artículo, espero que te haya sido de ayuda para Automatizar tus pruebas Web. Por favor, deja cualquier pregunta o comentario que tengas.