2009-02-02 8 views
9

Actualmente estoy desarrollando un pequeño proyecto mío que genera llamadas SQL de una manera dinámica para ser utilizado por otro software. Las llamadas SQL no se conocen de antemano y, por lo tanto, me gustaría poder probar el objeto que genera el SQL.¿Cómo pruebo una herramienta de generación de código?

¿Tiene alguna idea de cómo sería el mejor enfoque para hacer esto? Tenga en cuenta que no existe una forma posible de conocer todas las posibles llamadas SQL que se generarán.

Actualmente, la única idea que tengo es crear casos de prueba del SQL aceptado de la base de datos usando regex y asegurarme de que SQL se compilará, pero esto no garantiza que la llamada devuelva el resultado esperado.

Editado: la adición de más información:

Mi proyecto es una extensión de Boo que permitirá a los desarrolladores a etiquetar sus propiedades con un conjunto de atributos. Estos atributos se utilizan para identificar cómo los desarrolladores quieren almacenar el objeto en el DB. Por ejemplo:

# This attribute tells the Boo compiler extension that you want to 
# store the object in a MySQL db. The boo compiler extension will make sure that you meet 
# the requirements 
[Storable(MySQL)] 
class MyObject(): 
    # Tells the compiler that name is the PK 
    [PrimaryKey(Size = 25)] 
    [Property(Name)] 
    private name as String 

    [TableColumn(Size = 25)] 
    [Property(Surname)] 
    private surname as String 

    [TableColumn()] 
    [Property(Age)] 
    private age as int 

La gran idea es que el código generado no necesitará utilizar la reflexión, pero que será agregado a la clase en tiempo de compilación. Sí, la compilación llevará más tiempo, pero no será necesario usar Reflection en absoluto. Actualmente tengo el código funcionando generando los métodos necesarios que devuelve el SQL en tiempo de compilación, se agregan al objeto y se pueden llamar, pero necesito probar que el SQL generado es correcto: P

Respuesta

2

Esto parece una situación de huevo de gallina. No está seguro de qué escupirá el generador y si tiene un objetivo en movimiento para probar (la base de datos real). Entonces debes atar los cabos sueltos.

Crea una pequeña base de datos de prueba (por ejemplo, con HSQLDB o Derby). Esta base de datos debe usar las mismas funciones que la real, ¡pero no hagas una copia! Deberá comprender para qué sirve cada cosa en la base de datos de prueba y por qué está allí, así que invierta un poco de tiempo para encontrar algunos casos de prueba razonables. Use su generador de códigos en esta base de datos de prueba (estática), guarde los resultados como cadenas fijas en sus casos de prueba. Comience con una sola característica. No intente construir la base de datos de prueba perfecta como paso # 1. Llegarás ahí.

Cuando cambie el generador de código, ejecute las pruebas. Solo deberían romper en los lugares esperados. Si encuentra un error, replique la característica en cuestión en su base de datos de prueba. Crea una nueva prueba, verifica el resultado. ¿Se ve correcto? Si puede ver el error, corrija el resultado esperado en la prueba. Después de eso, arregle el generador para que cree el resultado correcto. Cierre el error y continúe.

De esta manera, puede construir cada vez más terreno seguro en un pantano. Haz algo que sabes, comprueba si funciona (ignora todo lo demás). Si estás satisfecho, sigue adelante. No trates de resolver todos los problemas a la vez. Un paso a la vez. Las pruebas no se olvidan, por lo que usted puede olvidarse de todo lo que se está probando y concentrarse en la próxima función. La prueba asegurará que su base estable siga creciendo hasta que pueda erigir su rascacielos en ella.

0

No tiene para probar todos los casos. Haga una colección de llamadas de ejemplo, asegúrese de incluir la mayor cantidad posible de los aspectos difíciles que la función tendrá que manejar, luego observe si el código generado es correcto.

0

Tendría un conjunto de pruebas que ingresan una entrada conocida y verifican que el SQL generado sea el esperado.

Nunca podrá escribir una prueba para cada escenario, pero si escribe lo suficiente para cubrir al menos los patrones más regulares, puede estar bastante seguro de que su generador funciona como se esperaba.

Si encuentra que no funciona en un escenario específico, escriba otra prueba para ese escenario y corríjalo.

1

expresiones regulares

Creo que la gramática de SQL es no regular, pero independiente del contexto; las subexpresiones son la clave para darse cuenta de esto. Es posible que desee escribir un analizador sin contexto para SQL para comprobar si hay errores de sintaxis.

Pero pregúntese: ¿qué es lo que quiere probar para? ¿Cuáles son sus criterios de corrección?

3

El objetivo de las pruebas unitarias es que conozca la respuesta para comparar los resultados del código. Tienes que encontrar una forma de conocer las llamadas SQL de antemano.

Para ser sincero, como han sugerido otros respondedores, su mejor enfoque es obtener algunos resultados esperados, y esencialmente codificarlos en las pruebas de su unidad. Luego puede ejecutar su código, obtener el resultado y compararlo con el valor esperado codificado.

¿Quizás pueda registrar el SQL real generado, en lugar de ejecutarlo y comparar los resultados también?

1

Si está generando el código, ¿por qué no también genera las pruebas?

Además de eso, probaría/depuraría el código generado de la misma manera que probaría/depuraría cualquier otro código sin pruebas unitarias (es decir, leyéndolo, ejecutándolo y haciéndolo revisar por otros).

+0

Desafortunadamente el código no se puede leer porque nunca se escribe, se agrega en el T de análisis utilizado por boo al compilar, y por lo tanto no se puede leer para que no sea posible leerlo y revisarlo :( – mandel

+0

No se puede agregar un paso intermedio donde el código se escribe en un archivo o algo así? –

+0

Sí, pero ¿eso significa que tengo que leer la salida para asegurarme de que funciona? Un poco horrible, ¿no? – mandel

Cuestiones relacionadas