Introducción a C#
Por Nacho Cabanes, versión 0.93 de 16-abr-2010


(Nota: Estás viendo una versión del curso antigua, creada en 2009. Es recomendable que sigas la versión 2015, mucho más actualizada, con contenidos más detallados, más ejemplos y más ejercicios propuestos)

11.3. Prueba de programas

Es frecuente que la corrección de ciertos errores introduzca a su vez errores nuevos. Por eso, una forma habitual de garantizar la calidad de los programas es creando una "batería de pruebas" que permita comprobar de forma automática que todo se comporta como debería. Así, antes de dar por definitiva una versión de un programa, se lanza la batería de pruebas y se verifica que los resultados son los esperados.

Una forma sencilla de crear una batería de pruebas es comprobando los resultados de operaciones conocidas. Vamos a ver un ejemplo, para un programa que calcule las soluciones de una ecuación de segundo grado.

La fórmula que emplearemos es:

Un programa (incorrecto) para resolverlo podría ser:

public class SegundoGrado {
 
    public static void Resolver(
          float a, float b, float c,
          out float x1, out float x2)
    {
 
 
        float discriminante;
 
        discriminante = b*b - 4*a*c;
 
        if (discriminante < 0)
        {
            x1 = -9999;
            x2 = -9999;
        }
        else if (discriminante == 0)
        {
            x1 = - b / (2*a);
            x2 = -9999;
        }
        else
        {
            x1 = (float) ((- b + Math.Sqrt(discriminante))/ 2*a);
            x2 = (float) ((- b - Math.Sqrt(discriminante))/ 2*a);
        }
 
    }
}
 

Es decir, si alguna solución no existe, se devuelve un valor falso, que no sea fácil que se obtenga en un caso habitual, como -9999.

Y la batería de pruebas podría basarse en varios casos conocidos. Por ejemplo:


x2 -1 = 0 -> x1 = 1, x2 = -1
x2 = 0 -> x1 = 0, x2 = No existe (solución única)
x2 -3x = 0 -> x1 = 3, x2 = 0
2x2 -2 = 0 -> x1 = 1, x2 = -1

Estos casos de prueba se podrían convertir en un programa como:

using System;
 
public class PruebaSegundoGrado {
 
    public static void Main(){
 
        float soluc1, soluc2;
 
        Console.WriteLine("Probando ecuaciones de segundo grado");
 
        SegundoGrado Ecuacion = new SegundoGrado();
 
        Console.Write("Probando x2 - 1 = 0 ...");
        SegundoGrado.Resolver((float)1, (float) 0, (float) -1, 
            out soluc1, out soluc2);
        if ((soluc1 == 1) && (soluc2 == -1))
            Console.WriteLine("OK");
        else
            Console.WriteLine("Falla");
 
 
        Console.Write("Probando x2 = 0 ...");
        SegundoGrado.Resolver((float)1, (float)0, (float)0,
            out soluc1, out soluc2);
        if ((soluc1 == 0) && (soluc2 == -9999))
            Console.WriteLine("OK");
        else
            Console.WriteLine("Falla");
 
        Console.Write("Probando x2 -3x = 0 ...");
        SegundoGrado.Resolver((float)1, (float)-3, (float)0,
            out soluc1, out soluc2);
        if ((soluc1 == 3) && (soluc2 == 0))
            Console.WriteLine("OK");
        else
            Console.WriteLine("Falla");
 
 
        Console.Write("Probando 2x2 - 2 = 0 ...");
        SegundoGrado.Resolver((float)2, (float)0, (float)-2,
            out soluc1, out soluc2);
        if ((soluc1 == 1) && (soluc2 == -1))
            Console.WriteLine("OK");
        else
            Console.WriteLine("Falla");
    }
}
 

El resultado de este programa es:


Probando ecuaciones de segundo grado
Probando x2 - 1 = 0 ...OK
Probando x2 = 0 ...OK
Probando x2 -3x = 0 ...OK
Probando 2x2 - 2 = 0 ...Falla

Vemos que en uno de los casos, la solución no es correcta. Revisaríamos los pasos que da nuestro programa, corregiríamos el fallo y volveríamos a lanzar las pruebas automatizadas. En este caso, el problema es que falta un paréntesis, para dividir entre (2*a), de modo que estamos diviendo entre 2 y luego multiplicando por a.

La ventaja de crear baterías de pruebas es que es una forma muy rápida de probar un programa, por lo que se puede aplicar tras cada pocos cambios para comprobar que todo es correcto. El inconveniente es que NO GARANTIZA que el programa sea correcto, sino sólo que no falla en ciertos casos. Por ejemplo, si la batería de pruebas anterior solo contuviera las tres primeras pruebas, no habría descubierto el fallo del programa.

Por tanto, las pruebas sólo permiten asegurar que el programa falla en caso de encontrar problemas, pero no permiten asegurar nada en caso de que no se encuentren problemas: puede que aun así exista un fallo que no hayamos detectado.

Para crear las baterías de pruebas, lo que más ayuda es la experiencia y el conocimiento del problema. Algunos expertos recomiendan que, si es posible, las pruebas las realice un equipo de desarrollo distinto al que ha realizado el proyecto principal, para evitar que se omitan cosas que se "den por supuestas".