TDD con SQL y funciones de manipulación de datos


14

Si bien soy un programador profesional, nunca he recibido capacitación formal en ingeniería de software. Como visito con frecuencia aquí y SO, noté una tendencia a escribir pruebas unitarias siempre que sea posible y, a medida que mi software se vuelve más complejo y sofisticado, veo las pruebas automatizadas como una buena idea para ayudar a la depuración.

Sin embargo, la mayor parte de mi trabajo implica escribir SQL complejo y luego procesar el resultado de alguna manera. ¿Cómo escribiría una prueba para asegurarse de que su SQL devolviera los datos correctos, por ejemplo? Luego, diga si los datos no estaban bajo su control (por ejemplo, el de un sistema de terceros), ¿cómo puede probar de manera eficiente sus rutinas de procesamiento sin tener que escribir a mano resmas de datos ficticios?

La mejor solución que se me ocurre es hacer vistas de los datos que, juntos, cubren la mayoría de los casos. Luego puedo unir esas vistas con mi SQL para ver si devuelve los registros correctos y procesar manualmente las vistas para ver si mis funciones, etc. están haciendo lo que se supone que deben hacer. Aún así, parece excesivo y escamoso; particularmente encontrar datos para probar contra ...


Respuestas:


6

Una regla importante para probar todo lo relacionado con la base de datos es aislarlo completamente del resto de su aplicación.

La arquitectura de puertos y adaptadores es un muy buen ejemplo. La base de datos se considera como un complemento externo a través de un adaptador para su aplicación. Lo mismo ocurre con todos los subsistemas de terceros. Para probar cómo se comportaría su aplicación e interpretaría las respuestas de los subsistemas de terceros, la única forma en que sé cómo probar eso es a tropezar las respuestas de este subsistema individual. No significa necesariamente que tendría que escribir manualmente todos los objetos de datos. Puede adoptar fácilmente el enfoque de usar pruebas basadas en datos.

Con respecto a probar cómo interactúa su aplicación con su base de datos, puede falsificar los adaptadores de la base de datos para utilizar una base de datos en memoria, por ejemplo.

Ahora prueba tus consultas de base de datos. En primer lugar, todas las consultas complejas deben descomponerse en consultas más fáciles, simples y predecibles. Lo mismo que harías para una clase de grasa o para una función de grasa. Hay herramientas que pueden ayudarlo a probar su base de datos como Dbunit. Un enfoque simple que a veces adopto es utilizar el concepto de pruebas de caracterización. Así que pondría la base de datos en un estado conocido, ejecutaría todas las consultas que tengo que escribir, guarde la salida en un lugar (archivo, memoria) y considere que esta salida es la correcta. Las siguientes ejecuciones compararían su salida con esta, por lo que definitivamente me ofrecerían las pruebas de regresión que necesito. De hecho, no se garantiza que el primer resultado sea correcto, pero el problema de regresión se puede resolver de esta manera. Si tiene sus consultas bien descompuestas, puede probarlas individualmente en la base de datos que se encuentra en un estado conocido.


3

Esa es una pregunta interesante porque la base de datos suele ser la parte que se falsifica durante la prueba de la unidad de aplicación. Esperemos que el proveedor pruebe bien la lógica del motor de la base de datos, pero, por supuesto, las consultas, el esquema y los procedimientos almacenados son códigos que deben probarse y protegerse contra la regresión. Esto a menudo se deja a las pruebas de integración que no es TDD.

Es probable que las vistas sean una forma difícil de hacerlo porque realmente no se prestan a la primera prueba automática de luz roja y luz verde de un aspecto por prueba que se prefiere en TDD. Además, con las vistas no puede escribir la prueba primero antes del código. Un mejor enfoque sería escribir procedimientos almacenados en los que pueda agregar lógica de "afirmación" en el procedimiento (por ejemplo, usando declaraciones "if") para probar la salida en busca de fallas. Debe probar solo una cosa en cada prueba de unidad para aislar la unidad, y el método SP sería más adecuado para eso. Además, con los SP, puede ejecutar todo el conjunto de ellos como scripts a medida que desarrolla el código inicial y luego al probar las regresiones al refactorizar.

Además, tenga en cuenta que las pruebas deben ser repetibles y necesitará algunas secuencias de comandos para inicializar y eliminar el estado de la base de datos para garantizar que el estado sea el mismo para cada prueba unitaria.

Para su pregunta sobre datos que no están bajo su control, esa es un área difícil. Creo que es mejor burlarse de él con datos falsos y probar la excepción y las condiciones de borde tanto como sea posible para las pruebas unitarias. De lo contrario, caerá más en la categoría de pruebas de integración (que también es algo bueno). Para las pruebas de integración, puede ejecutar sus pruebas contra los datos de terceros y dejar que genere una salida inicial y para las pruebas posteriores (por ejemplo, después de refactorizar) asegúrese de que esas salidas repitan la salida inicial conocida.


¿Por qué no puede escribir una prueba para una vista que aún no se ha codificado?
JeffO

No si está utilizando la vista como el mecanismo para la prueba como lo propuso el OP.
Llave en mano

1

En algún momento necesitarás datos de prueba. Si está utilizando un sistema de terceros, el esquema ya se ha creado, pero deberá abordar los cambios futuros. Con suerte, puede obtener estos cambios de la documentación de actualización, pero puede verse obligado a comparar las versiones de la base de datos usted mismo.

Los conjuntos de resultados esperados se pueden guardar en tablas de base de datos o archivos / hojas de cálculo externos. Incluso he visto CHECKSUM utilizado o comparación. Cuando prueba una vista / sproc, obtendrá un error ya que no existen. Luego, crea el objeto con código suficiente para al menos ejecutar (SELECT -1 como [wrong_data];) y obtendrá un error porque no coincide con el conjunto de resultados. Una vez que coinciden, tienes tu luz verde.

Comencé a trabajar con los propietarios de proyectos y les pido que se burlen de los informes en una hoja de cálculo e intenten obtener datos parciales para mí (podría poner los datos de resultados en una tabla de prueba). Al principio hubo un retroceso, pero se dieron cuenta de que voy a crear un informe y tendrán que verificarlo de todos modos. Esto ha ahorrado tiempo a largo plazo. Si quieren hacer una solicitud de cambio, pueden rehacer la hoja de cálculo. Ahora pueden responder la pregunta: "¿Qué tan difícil sería agregar ...?"


1

Si su plataforma de base de datos es SQL Server, hay una herramienta gratuita muy buena: tSQLt .

tSQLt es un marco de prueba de unidad de base de datos para Microsoft SQL Server. tSQLt es compatible con SQL Server 2005 (se requiere el service pack 2) y superior en todas las ediciones.

He utilizado con éxito para implementar pruebas a nivel de base de datos.

Algunos de los elementos clave que lo hacen tan útil incluyen:

  • Capacidad para trabajar con tablas y vistas falsas que reduce la configuración normal involucrada
  • Las pruebas se ejecutan automáticamente en las transacciones (tan fácil de volver a ejecutar)
  • Sus afirmaciones pueden hacer comparaciones en tablas (tanto reales como falsas) para que pueda ver si ha cambiado fácilmente alguna información.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.