1.10. Programación Extrema

He estudiado técnicas de análisis y diseño, de forma intermitente, desde que hice el posgrado. El concepto de Programación Extrema (XP) es el más radical y encantador que he visto nunca. Puede encontrar una crónica sobre el tema en Extreme Programming Explained de Kent Beck (Addison-Wesley 2000) y en la web www.xprogramming.com.

XP es una filosofía sobre el trabajo de programación y también un conjunto de directrices para hacerlo. Algunas de estas directrices se reflejan en otras metodologías recientes, pero las dos contribuciones más importantes y destacables, en mi opinión, son «escribir primero las pruebas» y la «programación en parejas». Aunque defiende con fuerza el proceso completo, Beck señala que si adopta únicamente estas dos prácticas mejorará sensiblemente su productividad y fiabilidad.

1.10.1. Escriba primero las pruebas

El proceso de prueba se ha relegado tradicionalmente a la parte final del proyecto, después de que «todo funcione, pero sólo para estar seguros». Implícitamente ha tenido una prioridad baja, y a la gente que se especializa en ello no se le ha dado mucha importancia, e incluso a menudo se la ha confinado en un sótano, lejos de los «programadores reales». Los equipos de pruebas han respondido con la misma moneda, llegando a vestir de negro y a reírse a carcajadas cada vez que rompían algo (para ser sincero, yo mismo he tenido esa sensación al romper compiladores de C++).

XP revoluciona completamente el concepto del proceso de prueba dándole la misma (o incluso mayor) prioridad que al código. De hecho, se escriben las pruebas antes de escribir el código que se va a probar, y las pruebas permanecen con el código siempre. Las pruebas se deben ejecutar con éxito cada vez que hace una integración del proyecto (algo que ocurre a menudo, a veces más de una vez al día).

Escribir primero las pruebas tiene dos efectos extremadamente importantes.

Primero, fuerza una definición clara de la interfaz de la clase. A menudo sugiero que la gente «imagine la clase perfecta para resolver un problema particular» como una herramienta cuando intenta diseñar el sistema. La estrategia del proceso de prueba de XP va más lejos que eso - especifica exactamente cuál debe ser el aspecto de la clase, para el consumidor de esa clase, y exactamente cómo debe comportarse la clase. Sin ambigüedad alguna. Puede escribir toda la prosa, o crear todos los diagramas que quiera describiendo cómo debe comportarse una clase y qué aspecto debe tener, pero nada es tan real como un conjunto de pruebas. Lo primero es una lista de deseos, pero las pruebas son un contrato que hacen cumplir el compilador y el programa en ejecución. Es difícil imaginar una descripción más concreta de una clase que las pruebas.

Mientras se crean las pruebas, el programador se ve obligado a pensar la clase por completo y a menudo descubrirá funcionalidades necesarias que podrían pasarse por alto durante los experimentos mentales de diagramas UML, tarjetas CRC, casos de uso, etc.

El segundo efecto importante de escribir las pruebas primero procede de la propia ejecución de las pruebas cada vez que hace una construcción del software. Esta actividad le ofrece la otra mitad de las pruebas, complementaria de la que efectúa el compilador. Si mira la evolución de los lenguajes de programación desde esta perspectiva, verá que las mejoras reales en la tecnología giran realmente alrededor del proceso de prueba. El lenguaje ensamblador sólo se fija en la sintaxis, pero C impone algunas restricciones de semántica, y éstas le impiden cometer ciertos tipos de errores. Los lenguajes POO imponen incluso más restricciones semánticas que, si lo piensa, son en realidad formas de prueba. «¿Se utiliza apropiadamente este tipo de datos? ¿Se invoca esta función del modo correcto?» son el tipo de pruebas que llevan a cabo el compilador o el sistema en tiempo de ejecución. Se han visto los resultados de tener estas pruebas incorporadas en el lenguaje: la gente ha sido capaz de escribir sistemas más complejos, y han funcionado, con mucho menos tiempo y esfuerzo. He tratado de comprender por qué ocurre eso, pero ahora me doy cuenta de que son las pruebas: el programador hace algo mal, y la red de seguridad de las pruebas incorporadas le dice que hay un problema y le indica dónde.

Pero las pruebas incorporadas que proporciona el diseño del lenguaje sólo pueden llegar hasta cierto punto. En algún momento, el programador debe intervenir y añadir el resto de las pruebas que producen un juego completo (en cooperación con el compilador y el sistema en tiempo de ejecución) que verifica el programa completo. Y, del mismo modo que tiene un compilador vigilando por encima de su hombro, ¿no querría que estas pruebas le ayudaran desde el principio? Por eso se escriben primero, y se ejecutan automáticamente con cada construcción del sistema. Sus pruebas se convierten en una extensión de la red de seguridad proporcionada por el lenguaje.

Una de las cosas que he descubierto sobre el uso de lenguajes de programación cada vez más poderosos es que me atrevo a hacer experimentos más audaces, porque sé que el lenguaje me ahorra la pérdida de tiempo que supone estar persiguiendo errores. El esquema de pruebas de XP hace lo mismo para el proyecto completo. Como sabe que sus pruebas siempre cazarán cualquier problema que introduzca (y regularmente añade nuevas pruebas a medida que se le ocurren), puede hacer grandes cambios cuando lo necesite sin preocuparse de causar un completo desastre. Eso es increíblemente poderoso.