miércoles, 13 de mayo de 2009

Testeos de regresión de aplicaciones que usan bases de datos

El tema de testeo es un tema complicado en general, y más complicado todavía cuando involucra aplicaciones que usan base de datos, como lo son las aplicaciones generadas con GeneXus.

Por suerte están surgiendo herramientas como GXTest o GXUnit que pretenden resolver el problema, aunque (por lo que se) todavía no han madurado demasiado. Creo que el testeo es un tema que está en el debe de la comunidad GeneXus en general.

Ya de paso le respondo a Enrique, una charla que estaría buena para el encuentro GeneXus, es alguien que tenga medianamente resuelto el problema del testeo, que cuente su experiencia.

En esta oportunidad quería comentar sobre un caso particular con el que me tocó enfrentarme.

Tenemos una base de conocimiento que tiene un proceso bastante complicado (tiene varios, uno en particular...), por la cantidad de casos particulares que hay que manejar. Cada vez que hay que hacer algo en ese proceso, terminamos rompiendo alguno de los casos particulares que ya estaban funcionando.

Tipico caso en el que se necesitan tests de regresión...

Hacer el testeo a mano de este proceso es bastante engorroso, porque involucra varios pasos previos (hay que crear varias entidades: cotización, carpeta, uno o más documentos, una o más órdenes de trabajo, etc.). Cada caso de prueba, dependiendo de la complejidad, puede llevar entre 5 y 10 minutos aproximádamente.

Entonces lo que estamos haciendo para automatizarlo es:
  1. tenemos una base de datos que se usa solo para el testeo automático, que tiene todos los datos básicos cargados.
  2. hay un script que borra (truncate table) todas las tablas operativas del sistema, para poder ejecutar cada caso en una base en blanco
  3. se diseña y ejecuta a mano el caso de prueba que se quiere registrar, hasta llegar al paso previo a presionar el botón que larga el proceso que queremos testear
  4. llegado a este punto, se genera (mediante un script SQL) un script SQL que genera todos los insert necesarios para dejar la base de datos en ese estado y se salva como script de inicialización para el caso de prueba
  5. se ejecuta el proceso y se verifica a mano que esté bien, y si es así se graba el resultado (el proceso genera información en una sola tabla...)
  6. se hace un procedimiento en GeneXus que carga un SDT con los valores esperados (los obtenidos en el paso anterior) y otro SDT con los valores reales haciendo un for each a la tabla, y se llama a otro que compara los SDTs campo a campo
  7. se agrega el caso de prueba al programa main de testeo.
Una vez hechos todos esos pasos, se puede ejecutar el caso de prueba todas las veces que se quiera, lo que es prácticamente instantaneo.

Por ahora es algo con lo que estamos experimentando. Desarrollar todo este procedimiento de testeo llevó algún tiempo, así como hacer los programas la primera vez, pero ahora el costo de agregar un nuevo caso de prueba es relativamente bajo, en relación al tiempo de testeo que va a ahorrar y la tranquilidad que nos da.

Creo que como experiencia sirvió, lo que no logro ver todavía es como extender esto a N situaciones distintas, porque por ahora es solo un proceso el que estamos testeando...

¿Alguien tiene experiencia de testeo con bases de datos? ¿Alguien más hace testeo automático?

4 comentarios:

  1. Marcos, mi experiencia es "pobre", pero te comento que ha sido muy similar a la que tú mencionas.

    Se asemeja mucho a la prueba unitaria, tengo una entrada y espero una determinada salida.

    Con los años cambie mucho la técnica de "probemos un modulo completo", por la idea de implementar todo de forma modularizada, con lo que el control de las pruebas se acotan mucho (solo tengo que probar el módulo al cual le hice las adaptaciones y los módulos que pueden ser afectados por la diferencia en los resultados).

    Lo otro es que todo lo intento pensar como un servicio de entrada/salida, hace que sea mas simple comparar las salida (otro módulo se encarga de almacenar o impactar los resultados en la BD).

    Eso si, "el macro" con todo unido ya se hace complicado de probar en su completitud, y termino utilizando la vieja técnica de "foto/proceso/backup->levanto foto/aplico cambios/proceso/comparo backups".

    De todas formas muchas veces salgo del paso con solo probar los módulos de forma independiente y en ocasiones simulando parcialmente módulos más completos.

    Sobre el tema de los N casos, me voy siempre hacia los casos más representativos, en ocasiones las variantes son tan grandes que sería imposible crear todos los casos posibles (La combinatoria de módulos hace que los casos de pruebas sean miles, si tengo acotado las pruebas de cada módulo no necesito crearme las miles de variantes de prueba).

    Para el UI, se me complica siempre, si hago que el UI tenga lo mínimo en lógica de negocio, se hace más fácil probar el back que el front, por suerte la gente de Abstracta está implementando algo que ayudará en esos momentos (GXTest).

    Conozco gente que se metió en el tema de pruebas automáticas con pruebas de UI, pero es algo muy complejo que termina dando muchos problemas (Ni loco me pienso meter a hacer scripts de Sellenium,OpenSta,Watir o Watin).

    Arriba GXTest y GXUnit!! se que pretenden resolver parte del problema.

    Aún queda mucho por hacer con respecto a las pruebas con BD en el medio.

    Lástima que sean pocos los que se meten de forma seria a intentar resolverlo, es un juego entre Costo/Beneficio.

    Para aplicaciones simples el costo de mantener y ejecutar todos los automatismos parece ser muy alto frente al costo de "hacerlo a la antigua", para las aplicaciones medianas, el costo parece razonable, la balanza se pone al mismo nivel.
    Sin embargo, cuando las aplicaciones ya son muy grandes la balanza se mueve en sentido contrario, el costo de simular una prueba es tan alto que aparece la necesidad de automatizar las mismas.

    ResponderEliminar
  2. Marcos,
    Me parece muy interesante la solución que encontraron. Es por lo que entiendo muy eficiente y permite tal como tu dijiste agregar fácilmente casos de pruebas nuevos sin mucho trabajo.

    Uno de los puntos claves en las pruebas de regresión es como se adaptan las mismas a los cambios de la aplicación. En la solución que planteas me parece que el único impacto puede venir por cambios en el esquema de la BD. En ese caso deberías ver de generar de nuevo los datos y el script de inicialización o "adaptar" los datos viejos no?

    Me parece que para todo proyecto de automatización hay un gran "pienso" (como el que hicieron ustedes) que ninguna herramienta te puede ayudar, pero para implementar la solución si te puede venir bien una herramienta.

    Si se tratara de una aplicación web, en este caso en particular GXtest te podría ayudar a cargar los datos de entrada utilizando la propia aplicación (de este modo sería más flexible a los cambios en el esquema de la BD pero sería mucho más largo el tiempo de ejecución). A lo mejor se puede incluso plantear una solución combinada para la carga inicial de datos (problema siempre recurrente en las pruebas de regresión).
    Lo otro en lo que puede ayudar es en la ejecución totalmente automática y agendada de los pasos que comentas.

    Aprovecho para contarte que para el evento GeneXus de este año seguramente vamos a presentar una charla sobre GXtest y su aplicación en K2B en donde vamos a poder discutir mejor estos temas que son complejos y de interés para toda la comunidad. En el evento también va a estar disponible la versión comercial del producto.

    Muy bueno el post
    Saludos

    ResponderEliminar
  3. Hola, quería felicitarte por tu pagina, es excelente, si queres, pasa por mi pagina y dejame un comentario, tengo mucho trafico en mi sitio, si te interesa podemos hacer un intercambio de links, banners, cualquier cosa avisame, te dejo mi email tvinternet08@gmail.com, te mando un abrazo.

    El equipo de Marketing Mega Virtual

    ResponderEliminar
  4. Matías: el cambio en el esquema de la base de datos es todo un tema...

    La forma de resolverlo dependerá del tamaño del cambio. Si se agrega un atributo, no es muy difícil agregarlo a los scripts de inicialización. Si es un cambio más grande, habrá que evaluar si es mejor cambiar los scripts o generarlos de nuevo.

    El otro tema que tampoco tengo resuelto es que hacer cuando varía el resultado esperado de una prueba... En principio fallarán los casos que tengan que fallar y habrá que arreglar los valores esperados.

    Guardame un lugar para la charla en el encuentro ;)

    ResponderEliminar