Content uploaded by Pedro Luis Mateo Navarro
Author content
All content in this area was uploaded by Pedro Luis Mateo Navarro on Feb 07, 2014
Content may be subject to copyright.
Verificación de Datos en la GUI como un Aspecto
Separado de las Aplicaciones
Pedro Luis Mateo Navarro
1,2
, Gregorio Martínez Pérez
1
, Diego Sevilla Ruiz
2
1
Departamento de Ingeniería de la Información y las Comunicaciones
2
Departamento de Ingeniería y Tecnología de Computadores
Universidad de Murcia, 30.071 Murcia, España
{pedromateo, gregorio, dsevilla}@um.es
Resumen. La verificación de datos es un elemento esencial y crítico dentro de
un software. Con este fin, en este trabajo se propone un framework que describe
una capa de verificación situada entre la interfaz gráfica (GUI) y la lógica de
aplicación. Esta capa analiza los eventos GUI generados por la interacción del
usuario para detectar cambios, ante los cuales lanza un proceso de
comprobación sobre los requisitos asociados al elemento interactuado. Además,
la capa puede realizar intervenciones sobre la GUI, completando así un proceso
de verificación rico e interactivo. Esta solución trata la verificación de datos
como un aspecto independiente, donde la lógica del proceso es transparente al
desarrollador, y las reglas se incluyen en ficheros separados.
Palabras clave: Verificación Entrada/Salida, Verificación GUI, Verificación
en Tiempo Real, Software Orientado a Aspectos.
1 Introducción
Según el estándar IEEE 1012-2004 [23], la Verificación y Validación Software
(V&V) tiene como principal fin determinar, durante el ciclo de vida del software, si
los requisitos del propio software y del sistema son correctos, completos, precisos y
consistentes, y asegurar así la calidad de un producto software. Los procesos de
Validación y Verificación de la Entrada surgieron para asegurar que sólo las entradas
válidas sean aceptadas, y las que no, sean rechazadas [14]. Un caso especial es la
Verificación Runtime (RV), donde la especificación de requisitos se comprueba en
tiempo de ejecución sobre la propia ejecución de la aplicación [5], en vez de sobre un
modelo, un diseño, o un trozo de código como hacen las técnicas estáticas [4].
La solución propuesta también está basada en el Desarrollo de Software Orientado
a Aspectos (AOSD), ya que el proceso de verificación queda aislado de la lógica
principal, consiguiendo así una mayor modularidad, encapsulación y especialización.
Este trabajo se centra en el procesamiento dinámico de la entrada de datos a través
de la interfaz gráfica (GUI). En las GUIs, tanto las entradas proporcionadas por los
usuarios como las generadas automáticamente son propensas a errores [10]. Por lo
tanto, con el fin de evitar un mal funcionamiento del software, resulta imprescindible
que los sistemas sean tolerantes a los datos, y puedan responder adecuadamente ante
valores esperados e inesperados. Esto nos lleva a proponer este framework, el cual
describe una capa de verificación situada entre la GUI y la lógica de aplicación. Esta
capa de verificación analiza los eventos GUI para monitorizar los cambios
producidos. Ante un cambio, se buscan todas las reglas del SRS (Especificación de
Requisitos Software) relacionadas con el campo modificado, y se comprueban sobre
el estado actual de la GUI.
El resto del artículo se estructura como sigue. El trabajo relacionado es comentado
en la Sección 2. En la sección 3 se comenta el enfoque de verificación propuesto, y en
la Sección 4 se incluyen algunas discusiones. Finalmente, en la Sección 5 se añaden
unas conclusiones y se comentan las líneas de trabajo futuro.
2 Estado del Arte
En esta sección se analizan una serie de soluciones que, al igual que la propuesta
en este trabajo, se centran en mejorar la calidad del software mediante el uso de
procesos RV. El primer ejemplo es RAVEN [9], un framework para la validación de
propiedades de accesibilidad en GUIs Java. Se trata de un inspector de propiedades
que valida mientras la aplicación está siendo usada. RAVEN posee un conjunto de
reglas asociadas a cada tipo Java definidas en un lenguaje propio basado en XML.
Otras soluciones utilizan lógicas formales para validar propiedades. Barringer et
al. describen en [2] un framework general para monitorizado de propiedades sin
estado (no almacena la traza de ejecución) basado en la lógica EAGLE. MaCS [12] es
otra herramienta cuyo objetivo es corregir el comportamiento del sistema en tiempo
de ejecución. Utiliza un filtro de eventos (cambios en la aplicación); cada uno de los
eventos está ligado a una serie de propiedades que deben ser validadas. Las
validaciones pueden implicar acciones para corregir el comportamiento de la
aplicación. En [26] Zee et al. describen una solución que combina validación estática
y en tiempo de ejecución basada en Jahob. Jahob utiliza fórmulas de alto orden
lógico (HOL) que son comprobadas constantemente en tiempo de ejecución como si
de un invariante se tratara. RuleR y LogScope son otros dos sistemas basados en
reglas propuestos por Barringuer et al. en [3]. El primero utiliza reglas single-shot
(escritas en lógicas temporales) que operan sobre una colección de estados. El
segundo es una derivación de RuleR en la que la especificación está basada en
patrones de alto nivel que internamente son traducidos a un autómata.
En [5] Chen y Rosu presentan MOP, un framework que genera monitores
encargados de comprobar ciertas restricciones sobre las propiedades seleccionadas.
Éstos son posteriormente integrados en el código de la aplicación. Para realizar las
comprobaciones, MOP utiliza instantáneas del estado de la aplicación extraídas en
tiempo de ejecución, llamadas “eventos”. En dicho trabajo hacen referencia a
soluciones como Tracematches [1] (Alian et al.) y J-LO [4] (Bodden), las cuales usan
pointcuts de AspectJ [6] para disparar la ejecución de pequeñas piezas de código que
validan propiedades. Por último, Falcone et al. describen en [8] unos monitores
especiales para modificar propiedades en tiempo de ejecución, llamados Enforcement
Monitors. En caso de que la comprobación de ciertas reglas no tenga éxito, dichos
monitores corrigen el error para que el flujo de ejecución no se desvíe del
comportamiento deseado. Estos monitores están basados en el Autómata de
Seguridad (Schneider [25]) y el Autómata de Edición (Ligatti et al. [13]).
En trabajos anteriores se propuso el Open HMI Tester [15,20], un framework
abierto y adaptable para el desarrollo de herramientas de pruebas. Este framework es
capaz de extraer la información incluida en los eventos GUI generados por la
interacción del usuario utilizando introspección no intrusiva. Como resultado se
presentó un prototipo de código abierto para el sistema de ventanas Qt [24], que fue
implantado con éxito en escenarios industriales. En [16,21,20] se presentó una
solución para generar automáticamente casos de prueba sobre GUIs. Para ello se
utilizaban anotaciones que incluían, para cada elemento relevante de la GUI, los
valores soportados y ciertas reglas de validación asociadas a esos valores.
3 Proceso de Verificación de Datos Orientado a Aspectos
Las GUIs se usan básicamente para la introducción de datos y para que el sistema
muestre los resultados. En ambos casos los datos deberían ser verificados para evitar
efectos no deseados, y también para comprobar su coherencia y consistencia.
Tradicionalmente las comprobaciones suelen realizarse en la lógica de aplicación, y
más raramente en el código de los widgets. En la primera, las reglas se incluyen en el
código de los métodos manejadores, empeorando la legibilidad del código, y por tanto
los procesos de depuración y mantenimiento. En la otra, las reglas están en la propia
especificación de la GUI, cuando deberían estar en el controlador. Además, la gestión
de un flujo de log único para verificación suele ser compleja en ambos enfoques.
Fig. 1: Vista general de la Capa de Verificación
3.1 Propuesta de Verificación como un Aspecto Separado del Software
El enfoque propuesto en este artículo describe un framework abierto y adaptable que
despliega una capa de verificación entre la GUI y la lógica de aplicación (Figura 1).
Esta capa representa un elemento independiente dentro del software capaz de analizar,
dinámicamente y de forma transparente, el flujo de eventos GUI generado por la
interacción del usuario y la lógica. Como se aprecia en la Figura 2, ese análisis
permite detectar los cambios realizados en la GUI. Una vez identificado el elemento
modificado, se buscan sus reglas de verificación, las cuales representan los requisitos
asociados a dicho elemento. Luego, éstas se comprueban sobre el estado actual de la
GUI para asegurar que todos los requisitos se cumplen. Si todas las reglas se cumplen,
el evento continúa el flujo normal hacia la lógica de aplicación para ser manejado. En
caso contrario, la Capa de Verificación responde con el comportamiento adecuado
(e.g. mostrar un mensaje, colorear el elemento, sugerir el formato esperado, etc.)
Podemos diferenciar entre verificación top-down (intercepta los cambios realizados
por el usuario para evitar entradas inválidas) y bottom-up (comprueba si los valores
establecidos por la lógica de aplicación en la GUI también son correctos). Además,
esta técnica es dinámica y permanente, ya que las reglas son comprobadas en tiempo
de ejecución como si se trataran de un invariante en Diseño por Contrato [18]. Esta
solución también está basada en el concepto AOSD, ya que el proceso de verificación
se trata y gestiona como un aspecto aparte dentro de la propia aplicación. Por último,
esta solución no utiliza un modelo joint-point como los lenguajes orientados a
aspectos (AOP) más utilizados [6,7], sino que es no intrusiva en código.
Fig. 2: Funcionamiento de la verificación top-down
En la Figura 3 podemos ver un ejemplo real de verificación hacia abajo. El usuario
establece el valor del campo Buffer Size a 25, el cual sólo soporta valores enteros
menores o iguales que 20. Al abandonar dicho campo se genera un evento Focus Lost,
el cual es interceptado por la Capa de Verificación. Una vez interceptado, se buscan
las reglas asociadas al elemento y se comprueban sobre el estado actual de la GUI.
Tras la comprobación (en este caso hay un error), se actualiza el fichero de log de
verificación y se llevan a cabo las intervenciones GUI necesarias. En este caso, se
establece un valor por defecto (i.e. 0) y se decora con color rojo para indicar el error.
Fig. 3: Ejemplo real de verificación top-down
3.2 Las reglas de verificación
Las reglas representan los requisitos SRS referentes a los valores de entrada/salida.
Éstas pueden ser simples y hacer referencia a un sólo elemento (e.g. “w1.value >=
10”), o complejas, las cuales hacen referencia a más de un elemento y además pueden
incluir estructuras de control de flujo, funciones, etc. (e.g. “if (w1.selectedIndex() ==
2) then w2.isEmpty() == false”). Para definirlas es necesario un lenguaje que dé a los
desarrolladores flexibilidad suficiente para representar fielmente todos los requisitos.
Por esto, la solución propuesta no está ligada a ningún lenguaje en concreto, y son los
propios desarrolladores los que eligen el lenguaje utilizar (e.g. lenguajes de
restricciones como OCL [22], de script como Ruby [17] o JavaScript [19], etc.)
Ya que la solución propuesta es orientada a aspectos, se utilizan ficheros externos
para separar las reglas del código fuente. Así, las reglas relacionadas se incluirían en
el mismo fichero, y el resto en ficheros diferentes. De esta manera se aumenta la
encapsulación y modularidad, facilitando la reutilización de la especificación de
verificación. Además, facilita la realización de otros procesos tales como la
depuración o la auditoría. Usar ficheros externos para las reglas también permite
cambiar la especificación de verificación en tiempo de ejecución, muy útil durante el
Proceso de Desarrollo. Por ejemplo, durante la fase de pruebas, los desarrolladores
podrían cambiar o ajustar las reglas sin necesidad de recompilar ni de volver a lanzar
la aplicación. Otro ejemplo sería el de cambiar la especificación completa en caso de
que aparezca un nuevo diálogo en la GUI, cambie el estado de la aplicación, etc.
La Figura 4 representa el proceso de carga de reglas, las cuales se obtienen a partir
de los ficheros facilitados por los desarrolladores (o los propios usuarios). Éstas deben
ser cargadas al lanzar la aplicación, y actualizadas cada vez que alguno de estos
ficheros cambie. Después, los elementos GUI se registran en la Capa de Verificación
para que puedan ser verificados. Finalmente, en la fase de enlace, se decide qué reglas
deberán ser comprobadas cuando se interactúa con un elemento concreto de la GUI.
Fig. 4: Proceso de carga de reglas
4 Discusiones
La solución propuesta describe un entorno para diseñar, implementar, probar, y
desplegar una solución completa de verificación en un software. Además, las técnicas
de Intervención GUI mejoran la experiencia del usuario, ofreciendo un proceso de
verificación más rico e interactivo. Tras las pruebas realizadas, se ha observado un
coste computacional despreciable ( 0.3ms/acción); además, se utilizan los intervalos≈
de tiempo existentes entre las acciones que componen la interacción del usuario.
Su naturaleza orientada a aspectos hace que la solución propuesta sea no invasiva e
independiente del código. La separación lógica entre código y reglas permite una
mayor encapsulación y modularidad. Por una parte se mejora la legibilidad del
código, facilitando los procesos de desarrollo y depuración. Por otra, mejora la
eficiencia en los procesos que trabajan con las reglas, y mejora su reutilización. El
hecho de que las reglas puedan ser modificadas en tiempo de ejecución es otra ventaja
interesante de este modelo. Finalmente, poder utilizar lenguajes de script proporciona
a los desarrolladores una gran flexibilidad al especificar las reglas.
Otro beneficio inherente parte de la necesidad de trabajar en profundidad, y desde
el inicio del proceso de desarrollo, en el análisis de requisitos. Esto permitiría detectar
posibles errores no detectados previamente en la fase de análisis, mejorando así la
especificación de requisitos (SRS) y el propio diseño de la GUI [10] desde el inicio.
Entre sus principales limitaciones, la desestructuración de los requisitos (reglas), la
imposibilidad de establecer todos los requisitos (e.g. los que dependen de valores
almacenados en BBDD), y las limitaciones de los módulos de intervención GUI.
5 Conclusiones y Trabajo Futuro
La verificación de la entrada es un elemento esencial y crítico dentro del Proceso
de Desarrollo Software. Por eso, se propone un framework abierto y adaptable que
describe una capa de verificación situada entre la GUI y la lógica de aplicación.
Esta solución AOSD se integra fácilmente en un software, y trabaja en paralelo
mientras la aplicación está en ejecución. La lógica de verificación es transparente, y
las reglas se incluyen en ficheros separados. Este framework permite implementar una
solución completa de verificación que convierte al proceso en una parte integral de las
etapas de desarrollo, pruebas, y ejecución del software. Además, su carácter abierto
no lo restringe a ningún sistema de ventanas o lenguaje de verificación concretos.
Nuestro siguiente objetivo es encontrar un framework más general (no sólo para
verificación) pasando de un modelo (Evento GUI Comprobación de Reglas) a un⇒
modelo (Elemento GUI + Evento GUI Acción). Esto facilitaría la implementación⇒
ágil de soluciones GUI orientadas a aspectos, por ejemplo el Prototipado Rápido de
GUIs, GUI Mocking Ágil, procesos de GUI Logging & Auditing, Software Adaptable,
etc., o incluso para usarlo como un nuevo modelo de desarrollo donde la definición de
la GUI y los métodos manejadores están separados y son intercambiables.
Agradecimientos
Este trabajo ha sido parcialmente financiado por la Cátedra SAES de la Universidad
de Murcia (http://www.um.es/catedrasaes). Este acuerdo engloba un esfuerzo
conjunto entre la empresa SAES (Sociedad Anónima Electrónica Submarina
(http://www.electronica-submarina.com) y la Universidad de Murcia, para trabajar en
software de código abierto y en sistemas de tiempo real y aplicaciones críticas.
Referencias
[1] Allan, C., Avgustinov, P., Christensen, A. S., Hendren, L. J., Kuzins, S., Lhotak, O., de Moor, O.,
Sereni, D., Sittampalam, G., and Tibble, J. Adding trace matching with free variables to AspectJ. In
OOPSLA (2005), R. Johnson and R. P. Gabriel, Eds., ACM, pp. 345–364.
[2] Barringer, H., Goldberg, A., Havelund, K., and Sen, K. Rule-based Runtime Verification. Verification,
Model Checking, and Abstract Interpretation (2004), Springer, pp. 44–57.
[3] Barringer, H., Havelund, K., Rydeheard, D. E., and Groce, A. Rule systems for runtime verification:
A short tutorial. In RV (2009), Bensalem and Peled, Eds., vol. 5779 LNCS, Springer, pp. 1–24.
[4] Bodden, E. J-LO-A tool for runtime-checking temporal assertions. In AOSD’08: Proceedings of the 7th
international conference on Aspect-oriented software development (2008), ACM, pp. 36–47.
[5] Chen, F., and Rosu, G. Mop: an efficient and generic runtime verification framework. In OOPSLA ’07:
Proceedings of the 22nd annual ACM SIGPLAN conference on Object-oriented programming systems
and applications (New York, NY, USA, 2007), ACM, pp. 569–588.
[6] Xerox Corp., AspectJ: The Aspect-Oriented language for Java. http://www.eclipse.org/aspectj/, 2010.
[7] Olaf Spinczyk et al,AspectC++: The Aspect-Oriented language for C++. http://www.aspectc.org/, 2010.
[8] Falcone, Y., Fernandez, J., and Mounier, L. Runtime Verification of safety-progress properties. In RV
(2009), S. Bensalem and D. Peled, Eds., vol. 5779 of LNCS, Springer, pp. 40–59.
[9] Feigenbaum, B., and Squillace, M. Accessibility validation with raven. In WoSQ ’06: Proceedings of
the 2006 international workshop on Software quality (New York, NY, USA, 2006), ACM, pp. 27–32.
[10] Hayes, J. H., and Offutt, J. Input validation analysis and testing. Empirical Software Engineering 11, 4
(2006), 493–522.
[11] Ierusalimschy, R. et al. Lua - The Programming Language. http://www.lua.org/, 2010.
[12] Kima, M., Leeb, I., Sammapunb, U., Shinb, J., and Sokolskyb, O. Monitoring, checking, and steering
of real-time systems. In RV’02, (FLoC Satellite Event) (December 2002), vol. 70, Elsevier, pp. 95–111.
[13] Ligatti, J., Bauer, L., and Walker, D. Enforcing non-safety security policies with program monitors. In
ESORICS (2005), Vimercati, Syverson, and Gollmann, Eds., vol. 3679 of LNCS, Springer, pp. 355–373.
[14] Liu, H., and Tan, H. B. K. Covering code behavior on input validation in functional testing.
Information and Software Technology 51, 2 (2009), 546 – 553.
[15] Mateo, P., Sevilla, D., and Martínez G., Open HMI Tester: An Open and Cross-Platform Architecture
for GUI Testing and Certification, in press. JCSSE (The International Joint Conference on Computer
Science and Software Engineering) Special Issue on Open Source Certification (February 2009).
[16] Mateo, P., Sevilla, D., and Martínez, G. A Proposal for Automatic Testing of GUIs Based on
Annotated Use Cases. Advances in Software Engineering 2010, 671284 (2010).
[17] Matsumoto, Y. The Ruby Scripting Language. http://www.ruby-lang.org/, 2010.
[18] Meyer, B. Applying ”design by contract”. Computer 25, 10 (1992), 40–51.
[19] Sun Microsystems. JavaScript Scripting Language. http://developers.sun.com/javascript/, 2010.
[20] Mateo, P., Martínez, G., and Sevilla, D. Open HMI Tester: un Framework Open-source para
Herramientas de Pruebas de Software. Actas de los Talleres de las Jornadas de Ingeniería del Software y
Bases de Datos 3, 4 (2009).
[21] Mateo, P., Martínez, G., and Sevilla, D. Automated GUI Testing Validation Guided by Annotated Use
Cases. In GI Jahrestagung (2009), Fischer, Maehle, and Reischuk, Eds., vol. 154 of LNI, pp. 2796–2804.
[22] Object Management Group. Object Constraint Language (OCL), version 2.0, OMG document
formal/2006-05-01, 2006. http://www.omg.org/spec/OCL/2.0/.
[23] IEEE. IEEE 1012-2004 - ieee standard for software verification and validation. IEEE, IEEE, pp. 0-
110. Revision of IEEE Std 1012-1998.
[24] Cátedra SAES of the University of Murcia, OpenHMI-Tester Prototype.
http://sourceforge.net/projects/openhmitester/, 2009.
[25] Schneider, F. B. Enforceable security policies. ACM Trans. Inf. Syst. Secur. 3, 1 (2000), 30–50.
[26] Zee, K., Kuncak, V., Taylor, M., and Rinard, M. C. Runtime checking for program verification. In
RV (2007), O. Sokolsky and S. Tasiran, Eds., vol. 4839 of LNCS, Springer, pp. 202–213.