salida procedimientos procedimiento parametros funciones español ejemplos ejecutar developer con almacenado 11g oracle unit-testing plsql tdd legacy

procedimientos - procedimiento almacenado oracle select



Cómo(unidad) prueba la aplicación PL/SQL intensiva de datos (4)

He usado DbFit para probar el código PL / SQL. Darle una oportunidad.

Nuestro equipo está dispuesto a probar la unidad de un nuevo código escrito en un proyecto en ejecución que amplía un enorme sistema Oracle existente.

El sistema está escrito únicamente en PL / SQL, consta de miles de tablas, cientos de paquetes de procedimientos almacenados, la mayoría de las veces obtiene datos de tablas y / o inserta / actualiza otros datos.

Nuestra extensión no es una excepción. La mayoría de las funciones devuelven datos de una bastante compleja SELECCIÓN de estado sobre muchas tablas mutuamente vinculadas (con un poco de lógica añadida antes de devolverlas) o hacen la transformación de una estructura de datos complicada a otra (complicada de otra manera).

¿Cuál es el mejor enfoque para probar la unidad de tal código?

No hay pruebas unitarias para la base de códigos existente. Para empeorar las cosas, solo los paquetes, desencadenadores y vistas son controlados por el origen, las estructuras de tabla (incluidas las tareas de "modificar tabla" y las transformaciones de datos necesarias se implementan a través de un canal que no sea el control de versión). No hay forma de cambiar esto dentro del alcance de nuestro proyecto.

Mantener el conjunto de datos de prueba parece ser imposible ya que cada semana se implementa un nuevo código en el entorno de producción, generalmente sin aviso previo, a menudo cambiando la estructura de datos (agregue una columna aquí, elimine una).

Me alegrará cualquier sugerencia o referencia para ayudarnos. Algunos miembros del equipo tienden a estar cansados ​​al descubrir cómo comenzar nuestra experiencia con pruebas unitarias. No cubre los sistemas heredados con uso intensivo de datos PL / SQL (solo aquellos proyectos greenfield "desde el libro").


utPLSQL podría ayudar, pero parece que necesita una mejor forma de mantener los datos de prueba. Es posible que también desee ver Swingbench para eso.


Hay varias herramientas de prueba diferentes para PL / SQL. Steven Feuerstein ha escrito dos de ellos, utplsql y Quest Code Tester for Oracle (anteriormente QUTE). Soy un gran fanático de utplsql, pero ya no cuenta con una comunidad de soporte activa (lo cual es una pena). También tiende a ser bastante detallado, especialmente cuando se trata de configurar los dispositivos de prueba. Tiene el cardenal virtual de ser paquetes PL / SQL puros ; el código fuente es un poco retorcido pero es FOSS.

QCTO viene con una GUI, lo que significa que, al igual que otros productos de Quest, es decir, TOAD, solo es Windows. No automatiza exactamente la generación de datos de prueba, pero proporciona una interfaz para admitirlo. También al igual que otros productos de Quest, QCTO tiene licencia aunque hay una copia gratuita.

Steven (revelación, él es uno de mis héroes de Oracle) ha escrito una comparación de características de todas las herramientas de prueba de PL / SQL. Obviamente, QOTC sale superando, pero creo que la comparación es honesta. Echale un vistazo.

Asesoramiento sobre accesorios de prueba en utplsql

La gestión de los datos de prueba para las pruebas unitarias puede ser un verdadero dolor en el cuello. Desafortunadamente, utplsql no ofrece mucho para soportar la carga. Asi que

  • Siempre prueba contra valores conocidos :
    • Evite usar dbms_random;
    • Intenta restringir el uso de secuencias a columnas cuyos valores no importan;
    • Las fechas también son difíciles. Evite las fechas de codificación difícil: use variables que se llenen con sysdate. Aprende a apreciar add_months() , last_day() , interval , trunc(sysdate, ''MM'') , etc.
  • Aísle los datos de prueba de otros usuarios. Constrúyelo desde cero. Use valores distintivos siempre que sea posible.
  • Solo crea tantos datos de prueba como necesites. Las pruebas volumétricas son una responsabilidad diferente.
  • Al probar procedimientos que cambian los datos, cree registros específicos para cada prueba unitaria.
  • Además: no confíe en el resultado exitoso de una prueba para proporcionar la entrada de otra prueba.
  • Cuando se prueban procedimientos que simplemente informan en contra de los registros de datos entre las pruebas unitarias cuando sea apropiado.
  • Comparta los datos del marco (por ejemplo, claves primarias referenciadas) siempre que sea posible.
  • Use campos de texto libre (nombres, descripciones, comentarios) para identificar qué prueba o pruebas usan el registro.
  • Minimice el trabajo involucrado en la creación de nuevos registros:
    • Solo asigne valores que sean necesarios para el conjunto de pruebas y las restricciones de la tabla;
    • Use valores predeterminados tanto como sea posible;
    • Proceduralize tanto como sea posible.

Otras cosas a tener en cuenta:

  • configurar un dispositivo de prueba puede ser un ejercicio que consume mucho tiempo. Si tiene muchos datos, considere la posibilidad de crear un procedimiento para configurar los datos estáticos que se pueden ejecutar una vez por sesión e incluir solo datos volátiles en el ut_setup mismo. Esto es especialmente útil cuando se prueba la funcionalidad de solo lectura.
  • recuerde que crear datos de prueba es un ejercicio de programación por derecho propio, y tan propenso a errores.
  • usa todas las características de utplsql. utAssert.EqQuery , utAssert.EqQueryValue , utAssert.EqTable , utAssert.EqTabCount y utAssert.Eq_RefC_Query son todas características muy útiles cuando se trata de inferir los valores de datos volátiles.
  • cuando diagnosticamos una prueba que no salió como esperábamos, puede ser útil tener los datos que se usaron. Así que considere tener un procedimiento de ut_teardown hueco y borrar los datos de prueba al inicio de ut_setup .

Tratando con código heredado

Comentar sobre la publicación de Gary me recordó otra cosa que puede serle útil. Steven F escribió ulplsql como una implementación PL / SQL de JUnit, la vanguardia de Java del movimiento Test First. Sin embargo, las técnicas de TDD también se pueden aplicar a grandes cantidades de código heredado (en este contexto, el código heredado es cualquier conjunto de programas sin ninguna prueba unitaria).

La clave a tener en cuenta es que no tiene que someter todo a prueba unitaria inmediatamente. Comienza incrementalmente Crear pruebas unitarias para cosas nuevas, Prueba primero . Cree pruebas unitarias para los bits que va a cambiar antes de aplicar el cambio, para que sepa que aún funcionan después de realizar el cambio.

Se piensa mucho en esta área, pero (inevitablemente, aunque vergonzosamente) proviene principalmente de los programadores de OO. Michael Feathers es el principal. Lea su artículo Trabajando eficazmente con Legacy Code . Si le resulta útil, posteriormente escribió un libro del mismo nombre.


Tome el siguiente escenario

FUNCTION ret_count (local_client_id IN number) RETURN NUMBER IS v_ret number; BEGIN SELECT count(*) INTO v_ret FROM table_1 WHERE client_id = local_client_id; RETURN v_ret; END;

Función muy simple, pero hay un montón de cosas que pueden salir mal. Las conversiones de tipo de datos, la indexación y las estadísticas podrían afectar las rutas de consulta, el rendimiento y, en algunos casos, los errores. También hay una gran cantidad de acoplamiento flexible, como la configuración de la sesión (por ejemplo, preferencias lingüísticas). Si alguien apareció y agregó una columna "LOCAL_CLIENT_ID" a la tabla_1, cambia toda la lógica de la función.

Personalmente, no creo que TDD sea adecuado para este entorno. Las revisiones de códigos por parte de personas conocedoras tendrán una mayor probabilidad de detectar problemas.

Si tiene dinero, mire la RAT (prueba de aplicación real) de Oracle para las pruebas de regresión.