Corregir los errores

Imagen de César

Probablemente usted haya visto esas imágenes de Windows colgándose el mismísimo momento en el que Bill Gates lo presentaba al público. ¿Ocurre esto porque Bill tiene muy mala suerte? ¿Porque Windows es muy malo? No, esto ocurre porque es un software complejo, y el software complejo esconde errores que le hacen fallar (a veces en el peor de los momentos).

¿Cómo se hace para quitar los errores del software? Bueno, pues... lo primero es encontrarlos.


Como encontrar errores en un software demasiado complejo sería como buscar una aguja en un pajar, la búsqueda comienza a hacerse componente a componente, a medida que estos se van programando. El programa estará formado por muchos (¡muchos!) pequeños componentes. El programador (u otra persona) probará el componente como si de un pequeño programa se tratara. Una vez que le de el visto bueno, pasará a formar parte del programa junto con el resto.

Una vez aquí, el componente, que no fallaba de modo aislado, puede comenzar a fallar debido a su interacción con otros componentes. Puede que el programador A y el programador B no se hayan puesto perfectamente de acuerdo en un tipo de dato que el componente A y el componente B intercambian en cierta operación, y entonces puede que se produzca el fallo que no se producía con los componentes aislados. O bien puede ocurrir que en su día al programador A se le escapó un fallo: cierta operación del componente A no se comportaba exactamente como debía comportarse. El programador B desarrolló su componente según el comportamiento real (no el esperado) del componente A. Más tarde, el programador A corrigió su error: ahora el componente A se comporta como siempre debió comportarse, pero no es ese el comportamiento que espera ahora el componente B. Cuando alguien introduce el componente A corregido, el componente B puede empezar a fallar debido al comportamiento corregido del componente A.

Viendo que un programa no trivial puede fácilmente estar compuesto por cientos o miles de componentes, que cada componente puede realizar decenas o cientos de operaciones distintas, y que probar cada operación puede implicar decenas de pruebas, empezaremos a comprender que probarlo absolutamente todo necesitaría tal cantidad de pruebas que ningún fabricante podría asumir su coste.

Y... ¿Habríamos terminado con esto de probarlo todo? Pues no. Es posible que el componente que en nuestra máquina funciona perfectamente, no funcione o no funcione bien en otra máquina. La primera razón es porque en esa segunda máquina nuestro componente puede interaccionar con componentes distintos que los que había en nuestra máquina. Volvemos al caso anterior pero con este nuevo factor de complejidad. Otra razón puede ser que nuestro componente realice alguna operación que sea sensible a la arquitectura de la máquina, y que esta sea distinta a la de nuestra máquina. Otra razón puede ser que la capacidad de la máquina sea distinta a la de la nuestra: así puede que en una máquina con menos recursos aparezcan fácilmente fallos que con más recursos quizás nunca encontraríamos, por ejemplo. Otra razón puede ser que en esa segunda máquina se estén ejecutando procesos que no se ejecutaban en la mía. Otra razón puede ser que yo no lo probé teniéndolo en ejecución durante el tiempo suficiente. Otra razón puede ser... ¡Hay tantas!

Pero supongamos que mediante ingeniería genética hemos conseguido crear el infornejo: un cruce perfecto entre informático y conejo, con la capacidad reproductora de este último pero con la capacidad de trabajo a bajo coste y en condiciones precarias del primero. En poco tiempo, gracias a su gran capacidad de reproducción, tenemos miles o decenas de miles de infornejos trabajando en probar nuestro programa. Incluso supongamos que uno de ellos ha digievolucionado a infornejo-mesías (algo así como archimago nivel 53) y es capaz de multiplicar las pruebas a su antojo, con lo que podemos probar todo lo que hemos dicho que había que probar, y en cualquier circunstancia. ¿Habríamos terminado con esto de probarlo todo? Pues no.

En este momento tendríamos un programa que funcionaría perfectamente... según lo pensó el programador. Pero, ¿lo pensó bien el programador? Podría ser que el cliente pidió un programa para el cálculo de nóminas y lo que el programador le entregó fue un juego de marcianos; un juego de marcianos, eso sí, que funciona perfectamente. Lo que queda por probar todavía es que el programa hace lo que tiene que hacer y como lo tiene que hacer. No siendo tan exagerados como en el ejemplo anterior (aunque esa es la idea), podría ocurrir que el programa no resultase fácil de manejar, que no hiciese las cosas de un modo operativo, natural, eficiente...

Para terminar de probar todo esto, el programador recurre a la realización de las llamadas pruebas alfa, que son pruebas que se realizan con usuarios utilizando el programa en un entorno controlado, bajo la supervisión del programador.

Si finalmente se superan también estas pruebas, el programa ya estaría listo para ser mostrado al mundo. Pero como (todavía) no tenemos infornejos, cuando el programa salga a recorrer mundo, en realidad, habrá pasado las pruebas que haya pasado, pero no se habrá probado todo. Sabedores de esto, lo que se hace es liberar una versión beta, previa a la versión final, para que un grupo selecto (pero no escaso) de usuarios la prueben.

Hasta aquí la explicación de la enorme dificultad que tiene dejar un programa sin sus errores naturales.

El proceso de buscar los errores y corregirlos se llama depuración. La depuración es una fase que fácilmente puede ser más costosa que el desarrollo de una "primera versión" del programa.

Hemos visto que los programas necesitan depuración. Hemos visto que la depuración de un programa es tan costosa que muy probablemente no termine nunca. Ahora la pregunta es: ¿Quién hace la depuración del programa?

La pregunta es tan interesante e importante, que te la voy a plantear como pregunta de tipo test, con posible respuesta múltiple, para que la respondas antes de seguir leyendo:

¿Quién hace la depuración del programa?

a) El programador

b) El usuario

c) El cliente

d) Me la suda

Por si las dudas: el programador es el que hace el programa, el usuario es quien usa un programa ya hecho, el cliente es quien paga al programador para que le haga el programa que necesita, y la última opción está clara.

SOLUCIÓN DEL TEST:

La opción "d" no es ninguna broma, y tiene que estar ahí. En esos días en los que me levanto de la cama con un optimismo exultante, estimo que el porcentaje de usuarios de informática a los que se la suda cómo funcionan las cosas, quién hace qué, y las consecuencias de las decisiones que consciente o inconscientemente toman, debe de estar bastante por encima del 99%. La opción debe estar ahí para ellos.

Si has escogido únicamente la opción "a", significa que estás todavía en las nubes; que, si has leído lo anterior, lo has hecho sin aprovechamiento. La opción "a" hay que escogerla, porque el programador es el que sabe corregir los errores en el código. Pero la depuración consta de dos tareas: encontrar los errores y corregirlos. Se necesitan recursos para corregir los errores, pero también se necesitan recursos para encontrarlos, y lo que debes entender es que se necesitan cada vez más recursos para encontrarlos a medida que estos van siendo cada vez más difíciles de encontrar.

Por tanto, la respuesta correcta (realista) es el programador y... alguien más. Acepto "b", "c", o "b y c". ¿Cuál es la (importante) diferencia?

Bien, pues... ya hemos dicho que las versiones beta de los programas son para que las prueben usuarios. Los usuarios usan los programas, y cada uso del programa es una prueba. Así que lo acertado es pensar que los programas muy usados están muy probados, y que tengas esto en cuenta cuando estés valorando qué programa usar para eso que quieres hacer. Si no encuentras ninguno que te satisfaga, tal vez recurras a pagar por un desarrollo a medida: entonces, te convertirás en el cliente. Y acepto el cliente como respuesta porque, en cuanto el vendedor te haga entrega del programa que has pagado, te convertirás en su usuario. Esto significa que comenzarás a usarlo, es decir, a hacer pruebas. ¡Pero esto no te lo dijo el vendedor!

Cuando el vendedor entró por tu puerta con su flamante corbata, te ofreció hacerte una nueva aplicación o directamente te ofreció su aplicación, que se adaptaría perfectamente a tus necesidades, estaría totalmente testeada, sería completamente estable... en fin, el Valhalla hecho software, vamos. Nunca te advirtió de que el programa podría tener errores o dar problemas (como todos los programas); nunca te advirtió de que la depuración te la ibas a comer tú, con o sin patatas.

De hecho, esto es tanto así que muchas veces los vendedores te ofrecen uno de estos "probadísimos" programas de los que no tienen ni una primera versión funcional. En no pocas ocasiones, no se empiezan los desarrollos hasta no tener los pedidos, cosa ética y legítima cuando el cliente es conocedor de ello y de lo que esto significa, pero no en otro caso.

Conocí en cierta ocasión un vendedor que esto lo explicaba diciendo que (cito lo más textualmente que puedo recordar):

Nosotros no mentimos, nosotros decimos verdades anticipadas (Es decir, no es cierto ahora que tengamos el programa ya desarrollado, pero lo será en el futuro, cuando lo tengamos.).

En cualquier caso, tú tienes que saber que los programas tienen fallos, y lo que tú tienes que hacer a la hora de escoger un programa para tu uso es estimar cuántos fallos tendrá y qué importancia tendrán esos fallos para ti. Un programa muy utilizado probablemente (esto no es una regla general) tendrá menos fallos y de menor importancia que uno poco utilizado. Si los fallos son poco importantes, te bastará con saber que esto es "lo normal" para evitarte frustraciones personales y resignarte a vivir con ellos. Pero si son importantes para ti (porque afecten a tu negocio, por ejemplo), habrá que arreglarlos. Piensa entonces que si a tu coche se le fundiesen las bombillas sería malo, pero que no se las pudieses cambiar sería muchísimo peor.

Y recuerda que para corregir los errores en un programa, es necesario tener acceso a su código fuente.