2010-04-19 72 views
9

Nuestro equipo está dispuesto a probar en unidades un nuevo código escrito en un proyecto en ejecución que amplía un enorme sistema Oracle existente.Cómo (unidad) prueba la aplicación de PL/SQL con uso intensivo de datos

El sistema está escrito únicamente en PL/SQL, consta de miles de tablas, cientos de paquetes de procedimientos almacenados, la mayoría de las cuales obtienen datos de tablas y/o insertan/actualizan 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 de unidad 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 (incluida la información 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 imposible ya que cada semana se implementan nuevos códigos en el entorno de producción, generalmente sin aviso previo, a menudo cambiando la estructura de datos (agregue una columna aquí, elimine una).

Estaría encantado de 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").

Respuesta

8

Existen 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 cardinal virtual de ser paquetes puros PL/SQL; el código fuente es un poco retorcido pero es FOSS.

QCTO viene con una GUI, lo que significa, al igual que otros productos de Quest, es decir, TOAD, solo 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. Check it out.

Asesoramiento en accesorios de la prueba en utplsql

datos de prueba Gerente de la unidad de pruebas puede ser un verdadero dolor en el cuello. Desafortunadamente, utplsql no ofrece mucho para soportar la carga.Así

  • siempre una prueba en contra valores conocidos:
    • Evitar el uso de dbms_random;
    • Intenta restringir el uso de secuencias a columnas cuyos valores no importan;
    • Las fechas también son complicadas. Evite las fechas de codificación difícil: use variables que se completen con sysdate. Aprende a apreciar add_months(), last_day(), interval, trunc(sysdate, 'MM'), etc.
  • aislar los datos de prueba de otros usuarios. Constrúyelo desde cero. Use valores distintivos siempre que sea posible.
  • Crea solo tantos datos de prueba como necesites. Las pruebas volumétricas son una responsabilidad diferente.
  • Al probar los procedimientos que modifican los datos, cree registros específicos para cada prueba unitaria.
  • También: no confíe en la salida exitosa de una prueba para proporcionar la entrada de otra prueba.
  • Cuando se prueban procedimientos que simplemente informan en contra de registros de datos compartidos entre pruebas unitarias cuando corresponde.
  • Comparta datos de marco (por ejemplo, claves primarias referenciadas) siempre que sea posible.
  • Utilice campos de texto libre (nombres, descripciones, comentarios) para identificar qué prueba o pruebas usan el registro.
  • Reducir al mínimo el trabajo implicado en la creación de nuevos registros:
    • Sólo asignar valores que son necesarios para el banco de pruebas y las limitaciones de la tabla;
    • Use los valores predeterminados tanto como sea posible;
    • Proceduresize tanto como sea posible.

Otras cosas a tener en cuenta:

  • la creación de un dispositivo de prueba puede ser un ejercicio que consume 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. Esto es especialmente útil cuando se prueba la funcionalidad de solo lectura.
  • recuerde que la creación de datos de prueba es un ejercicio de programación en sí mismo y tan propenso a errores.
  • utiliza todas las funciones 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.
  • al diagnosticar una ejecución de prueba que no salió como esperábamos puede ser útil para tener los datos que se utilizaron. Así que considere tener un procedimiento hueco ut_teardown y borrar los datos de prueba al inicio de ut_setup.

Tratar con el código heredado

Comentando en el post de Gary me recordó otra cosa que puede ser ú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).

Lo más importante a tener en cuenta es que no tiene que someter todo a prueba de la unidad de inmediato. Comienza incrementalmente Crear pruebas unitarias para cosas nuevas, Test First. 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.

Hay una gran cantidad de pensamiento en esta área, pero (inevitablemente si vergonzosamente) proviene principalmente de los programadores de OO. Michael Feathers es el principal. Lee su artículo Working Effectively With Legacy Code. Si le resulta útil, posteriormente escribió un libro del mismo nombre.

+0

Gracias por su respuesta. Soy consciente de utPLSQL, de hecho planeamos usarlo, pero mi pregunta no era mucho sobre herramientas en lugar de sobre el enfoque. Es bastante sencillo probar una función que devuelve valor en función de sus argumentos. Pero, ¿qué ocurre con un valor de retorno de función calculado a partir de una gran cantidad de datos (por ejemplo, el número de incumplimientos más largos que N en los últimos M meses en los que la cantidad vencida fue mayor que O). Preparar datos en forma de accesorios no es tan fácil, ya que cada función implica uniones de media docena de tablas y dado que "todo se relaciona con todo" en el sistema. –

1

utPLSQL podría ayudar, pero parece que necesita una forma mejor de mantener los datos de prueba. También puede consultar Swingbench para eso.

3

He usado DbFit para probar la unidad de código PL/SQL. Darle una oportunidad.

4

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 sencilla, pero hay un lío de cosas que pueden ir 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 de Oracle (prueba de aplicación real) para las pruebas de regresión.

+1

TDD solo aborda la corrección programática, por lo que la indexación, las estadísticas y el rendimiento son irrelevantes. Si tenemos un conjunto de pruebas automatizadas, es probable que recoja el impacto de que alguien agregue una columna LOCAL_CLIENT_ID a la tabla_1. He utilizado utplsql para compilar complicadas API PL/SQL de forma TDD. Funciona bien. – APC

+0

Aceptado. Con "adecuado" quería decir que sentía que no ofrecería mucha protección para el código que era pesado en la transformación de datos de SQL. –

Cuestiones relacionadas