Contrucción y modelado

El framework EMF, es una pieza fundamental en el modelado y construcción de la herramienta. Entre otras cosas, ha facilitado un proceso de desarrollo muy ágil, y el refinamiento sucesivo de los modelos a través de las iteraciones realizadas en el desarrollo.
Una de las características de Ecore es su capacidad para representar diagramas UML. Hay una relación directa entre cómo se definen los modelos Ecore, y cómo son serializados éstos en XMI; por ejemplo, el nombre de las clases Ecore se usan como nombre para las etiquetas XML, las relaciones de asociación se representan mediante un atributo en la etiqueta del objeto origen de la relación cuyo valor es el identificador del destino, etc.
Conocer las reglas que utiliza EMF para construir los ficheros XMI permitirá definir modelo Ecore que tengan sentido cuando sean serializados. En cada iteración de la elaboración de la herramienta, se crearon un conjunto de modelos Ecore que soportara la funcionalidad añadida. Posteriormente estos modelos fueron usados para generar código fuente Java y su persistencia en XMI; alrededor de la mitad del código fuente de la herramienta fue generado de forma automática gracias a las facilidades proporcionadas por EMF. A continuación se listan los modelos Ecore creados para cada una de las necesidades que se tuvieron que satisfacer.

Modelo de Datapool

El concepto de Datapool (DTP) incorpora la posibilidad de introducir datos de entrada para cada Caso de Prueba a través de una estructura generalmente representada en forma de tabla de datos. De esta forma si deseamos realizar un Caso de Prueba que ingresa al sistema un número elevado de registros nuevos podemos crear un DTP que los contenga. Después creamos un Script de Prueba, que automatice dicho Caso de Prueba, cuyos comandos utilicen el DTP definido para ingresar los valores en la aplicación y recorrer cada dato diferente del DTP cada vez que se ejecute el Caso de Prueba.
Esta forma de especificar valores de entrada en tablas es la que hemos utilizado en nuestro modelo Ecore tal y como se puede apreciar en la siguiente figura:

La funcionalidad de un DTP es implementada por la clase IODatapool. Dicha clase contiene atributos relacionados con información genérica del DTP como puede ser el nombre, ruta del artefacto y descripción del componente, así como las fechas de creación y modificación del DTP.
El DTP como hemos indicado, estará compuesto por unas columnas y filas que registran los datos de entrada. Cada columna representará un valor de entrada o salida de un Caso de Prueba. La clase que implementa esta idea es IODatapoolVariable y tendrá un nombre y un tipo de dato representado por un formato determinado que será validado. Los tipos de variables están predefinidos y para ello se ha creado un tipo de dato que determinará los posibles valores que podrá tomar una variable. La funcionalidad de una fila
viene descrita en la clase IODatapoolRow. Cada fila describe un conjunto de datos de entrada y salida que han de ser tratado por el Caso de Prueba en concreto. Los datos registrados en cada fila (IODatapoolRow) vienen expresados en la clase IOCell. Además, las celdas que conformen las filas, estarán relacionadas con las columnas de la tabla, en este caso IODatapoolVariable, formando con este tipo de relaciones una matriz de datos dispuesta en filas y columnas.
Cada DTP es gestionado en contenedores de forma independiente, como analizaremos en el siguiente modelo. A su vez, un DTP podrá estar asociado a varios escenarios para permitir su reutilización.


Modelos para la generación de pruebas

La siguiente figura  muestra el diagrama UML que modelaba la jerarquización de TCSs. El elemento raíz de la jerarquía de TCS es la clase IOTestCaseSetRoot que contiene un conjunto de TCSs, DTPs y de carpetas de TCS o DTPs, las cuales pueden contener a su vez más carpetas, TCSs o DTPs. Los elementos que pueden tener carpetas de TCSs o DTPs se han modelado extendiendo la clase abstracta IOTestCaseSetContainer. Los TCS se representan mediante la interfaz IOTestCaseSet, que tiene como atributos el nombre del testeador, las fechas de creación y última modificación, un comentario, y listados de necesidades hardware, software y varias. Un TCS puede estar asociado a uno o varios UCs que determinarán sus escenarios.

Tal y como se puede apreciar en la figura, la clase ITGSWTBotTestCaseSet permite incorporar en eOPSOA el concepto de prueba automática como aproximación para la elaboración de Conjuntos de Casos de Prueba. Este tipo de TCS, al igual que sucedía en el TCS manual, está compuesto por escenarios, y éstos por TCs. Así mismo, cada TC será descrito como un script de prueba que estará compuesto por una o más instrucciones. La idea reflejada en este párrafo, es representada en la siguiente figura:

Es necesario mencionar que la clase ITGSWTBotScenario implementa a una interfaz genérica llamada IOScenario. Esta interfaz genérica carece de atributos y métodos. Su función es la de poder adaptar y relacionar los modelos Ecore de necesarios para integrar SWTBot con los modelos Ecore implementados en la versión previa de la herramienta. Este patrón de diseño se utilizará cada vez que se necesite reflejar dicha integración.


Modelos para la composición de instrucciones

La principal novedad incorporada en la herramienta como hemos visto anteriormente, es el soporte para la automatización de pruebas. Con este fin, las instrucciones que se ejecutarán de forma automáticas se especificaran en contenedores que actuarán como Scripts de Pruebas. Por definición, un Scripts de Pruebas es el conjunto de datos e instrucciones escritas con una sintaxis formal, almacenado en un archivo y usado por una herramienta de automatización de las pruebas. La clase contenedora de instrucciones que alberga este concepto es ITGSWTBotMasterScript y su propósito es la de proporcionar la implementación del subconjunto de pruebas requeridas de una manera eficiente y eficaz. Tal y como muestra la siguiente figura, cada escenario estará compuesto de una clase contenedora de instrucciones ITGSWTBotMasterScript.


Tras analizar el concepto de Master Script, podemos pensar que la relación de composición entre ITGSWTBotTestCase y ITGSWTBotInstruction es innecesaria, ya que las instrucciones contenidas en el Master Script del escenario podrían ser las mismas que las contenidas en los Casos de Prueba generados a partir de dicho escenario. No obstante, tras generar estas instrucciones nos guardamos el derecho de modificarlas en el Caso de Prueba correspondiente, obteniendo así unas instrucciones diferentes a las albergadas en el Master Script que siguen manteniendo su integridad. Por ello mantenemos las dos relaciones de composiciones.
Algunas de las instrucciones que se ejecutarán de forma automática, podrán ser de salida o de entrada como hemos observado en Modelo de Datapool, respecto el Caso de Prueba. Por ello distinguiremos tres clases de instrucciones. Mientras que ITGSWTBotIntructionInput implementará las instrucciones relacionadas con el DTP, ITGSWTBotIntructionAssert contendrá las instrucciones de verificación del resultado esperado en el Caso de Prueba. El resto de instrucciones de acción se relegan a la clase ITGSWTBotIntructionAction. Las tres clases extenderán de la interfaz ITGSWTBotInstruction que aúna características que comparten todos los tipos de instrucciones como son los atributos elemento, nombre, identificador, un patrón de búsqueda del componente y de una acción a realizar en el componente, por la instrucción.
Las instrucciones de entrada representadas mediante ITGSWTBotIntructionInput, además de los atributos heredados, contendrán datos de prueba que provienen del DTP y que las instrucciones se encargarán de gestionar correctamente para el Caso de Prueba correspondiente. Además de este dato de entrada, la clase ITGSWTBotIntructionInput pedirá al DTP el tipo de variable datapool definida previamente. Este atributo realizará una validación interna para detectar que la composición de la instrucción está a salvo de errores.
De forma similar a las instrucciones de entrada, la clase ITGSWTBotIntructionAssert describe dos atributos, resultado esperado y tipo de resultado esperado, que permitirán validar la correcta construcción de la instrucción de salida. Además, el atributo subacción indicará el tipo de acción de comprobación a realizar por la instrucción.
La utilización una interfaz para especificar las instrucciones para permitir la ejecución automática de Casos de Prueba, permite seguir extendiendo y especificando en el futuro los tipos de instrucciones aceptadas por el traductor genérico SWTBot.



Modelo de mapeo de instrucciones

Se hace necesario un mecanismo que permita relacionar las instrucciones de entrada y salida descritas en el modelo de composición de instrucciones, con las diferentes columnas de un DTP expresadas como variables. Este mecanismo de mapeo es una técnica de programación muy utilizada para convertir datos entre sistema que utilizan un lenguaje de programación orientado a objetos y el utilizado en una base de datos relacional. En nuestro caso podemos asociar estas entidades con las instrucciones de entrada/salida y las variables del DTP, respectivamente. La siguiente figura muestra este concepto de relación entre variables e instrucciones. Estos mapeos serán parte de una composición contenida en un escenario. El estado de validez del mapeo lo indicará la enumeración OMappedStatus, y no será otro que válido o no válido.


Modelo para la actividad de Resultados de pruebas

Gracias a las facilidades de ejecución de pruebas automáticas podemos mostrar un gran nivel de detalle acerca de los resultados obtenidos en las pruebas. Tal y como se describe en la siguiente figura, este Log de Resultados se representa a través de la clase IOTestDocumentRoot. El Log de Resultados contiene una jerarquía de artefactos menores que describen las ejecuciones de un conjunto determinado de TCS.
Estas ejecuciones son representadas a través de IOTestRun y contienen información detallada de cada una de las ejecuciones tales como un id que identifica de forma unívoca cada una de las ejecuciones, la persona que ejecutó las pruebas, fecha, hora de comienzo y fin de cada una de estas comprobaciones de pruebas. Cada IOTestRun estará formado por un conjunto de Casos de Prueba (IOTestCaseRun) formados a su vez por instrucciones (IOInstructionRun) que hacen posible consultar el resultado de la ejecución de cada instrucción.