Ya hemos dicho que los casos de prueba son unidades que se encargan de realizar las pruebas de otras unidades, simplemente utilizándolas y verificando que se comportan como deberían.
Para que esto sea más tangible, vamos a poner un ejemplo "casi real": estamos en un sistema que tiene un módulo completo para cálculos aritméticos. Como estamos programando en C (todavía no sabemos qué es esa cosa del C++), tenemos en este módulo una unidad "suma" se representa por una única función: sumar(a, b).
int sumar(int a, int b);
{
return (a + b);
}
Podemos imaginar que pertenecemos al departamento de calidad (QA) de una gran empresa de desarrollo, y nos ha tocado desarrollar las pruebas unitarias para esta unidad que suma. Nuestra tarea consiste en escribir las pruebas, y lo haremos desde otra función, que retornará FALSE si alguna de las pruebas falla.
La función tiene un esquema fijo: una serie de sentencias de prueba en las que se verifica el caso correcto. En caso de retornarse un valor distinto al esperado, se retorna el valor de error.
int ProbarSumar()
{
if ( sumar(1, 2) != 3 )
return (FALSE);
if ( sumar(, ) != )
return (FALSE);
if ( sumar(10, ) != 10 )
return (FALSE);
if ( sumar(-8, ) != -8 )
return (FALSE);
if ( sumar(5, -5) != )
return (FALSE);
if ( sumar(-5, 2) != -3 )
return (FALSE);
if ( sumar(-4, -1) != -5 )
return (FALSE);
return (TRUE);
}
Después de esto, no se trata más que de llamar a esta función desde el
main, y mostrar un mensaje indicando el éxito o fracaso.
Como podéis ver, hemos probado los casos más típicos de suma:
- Positivo + Positivo
- Cero + Cero
- Positivo + Cero
- Negativo + Cero
- Positivo + Negativo
- Negativo + Positivo
- Negativo + Negativo
Cada una de las pruebas se compara con el resultado correcto, así, si la función "suma" retorna algún valor incorrecto, la función de prueba retornará un FALSE. En caso de pasarse todas las pruebas, la función retornará TRUE.
Esta prueba que acabo de hacer se llama "Caso de prueba" (
Test Case) y representa a un conjunto de verificaciones que hacemos sobre la misma unidad. Todas estas verificaciones deben estar relacionadas con un mismo aspecto (o caso de uso) de la unidad a probar, en nuestro caso: verificar los resultados de la suma teniendo en cuenta el signo de los operandos.
Podemos hacer distintos casos de prueba sobre la misma unidad, por ejemplo, cuando queremos probar distintos aspectos. En nuestro ejemplo podemos crear otro caso de prueba para probar las propiedades de la suma:
int ProbarPropiedadesSumar()
{
conmutativa: a + b = b + a
if ( sumar(1, 2) != sumar(2, 1) )
return (FALSE);
asociativa: a + (b + c) = (a + b) + c
if ( sumar(1, sumar(2, 3)) != sumar(sumar(1, 2), 3) )
return (FALSE);
elemento neutro: a + NEUTRO = a
if ( sumar(10, ) != 10 )
return (FALSE);
elemento inverso: a + INVERSO = NEUTRO
if ( sumar(10, -10) != )
return (FALSE);
return (TRUE);
}
En este caso de prueba hemos verificado que se cumplen las propiedades típicas de la suma. Lo siguiente que tendríamos que hacer es añadir este nuevo caso de prueba a la misma función
main de antes, y mostrar el resultado de ambas funciones. Así, nuestro programa de pruebas será algo así como esto:
int main(int argc, char
argv)
{
int ok, err;
printf("Casos de prueba sobre la unidad suma(a, b):");
ok = ;
err = ;
printf("\r\n\tProbando signos de la suma... ");
if ( ProbarSumarSignos() ) {
printf("ok!");
ok++;
}
else {
printf("ERROR");
err++;
}
printf("\r\n\tProbando propiedades de la suma... ");
if ( ProbarSumarSignos() ) {
printf("ok!");
ok++;
}
else {
printf("ERROR");
err++;
}
/* añadir otros casos de pruebas */
printf("\r\n\r\nResumen de las pruebas sobre la unidad suma:");
printf("\r\n\tCorrectas: %d", ok);
printf("\r\n\tErroneas: %d", err);
return (err);
}
Como ya dijimos, al conjunto de casos de prueba sobre una misma unidad se le llama "Colección de Pruebas" (Test Suite).