El Test de Joel: 12 pasos hacia un código mejor

From The Joel on Software Translation Project

Jump to: navigation, search

Por Joel Spolsky
Miércoles 9 de agosto de 2000
Artículo original: The Joel Test: 12 Steps to Better Code
Traducido por Pablo López
Contibuciones: Riledhel


¿Te suenan las siglas SEMA?. Es un sistema un tanto exótico de medir lo bueno que es un equipo de desarrollo de software. No, ¡espera!. ¡No sigas el enlace!. Te costaría unos seis años solamente entenderlo. Por eso he creado un cutre-test altamente irresponsable de mi propia cosecha para medir el nivel de calidad de un equipo de desarrollo. Lo bueno que tiene este test es que hacerlo cuesta unos tres minutos. Con todo el tiempo que te ahorrarás, puedes aprovechar y estudiar medicina.

El Test de Joel

Contents


Lo mejor del Test de Joel es que es muy fácil contestar a las respuestas: o sí o no. No tienes que empezar a hacer estimaciones como "lineas de código al día" o "media de fallos por punto función". Simplemente anota un punto para tu equipo por cada respuesta a la que hayas contestado "sí". La única pega que tiene el Test de Joel es que no sirve para verificar si el software de tu central nuclear es seguro.

Una puntuación de 12 es perfecta, 11 es tolerable, pero si has sacado 10 o menos estás en apuros. La verdad es que la mayoría de las empresas de software sacarían un 2 o un 3 y necesitan ayuda porque empresas como Microsoft están funcionando con una puntuación de 12 en todo momento.

Obviamente éstos nos son los únicos factores que determinan el éxito o el fracaso. Si tienes un estupendo equipo de desarrollo trabajando en un producto que nadie quiere, pues, ejem, nadie va a querer el producto. Y sí, es posible imaginar un equipo de superdotados que no sigan niguna de estas reglas y aun así se las apañen para crear software que cambie el mundo. Pero, en igualdad de condiciones, si cumples estas 12 reglas tendrás un equipo disciplinado que podrá crear productos de forma consistente.

¿Utilizas software de control de versiones?

He usado programas comerciales de control de versiones y he usado CVS, que es libre, y qué quieres que te diga, CVS está bien. Pero si no usas ningún software de control de versiones te vas a estresar intentando que los programadores trabajen en equipo. Los programadores no tienen forma de saber lo que han hecho los demás. Los errores no se pueden deshacer facilmente. Otra cosa fantástica del control de versiones es que el propio código fuente está replicado en el disco duro de todos los programadores. Nunca he oido hablar de ningún proyecto que usara control de versiones donde se perdiera mucho código.

¿Puedes generar el producto en un solo paso?

Con esto me refiero a: ¿cuántos pasos necesitas para generar un producto y tenerlo listo para instalar a partir de la última versión de su código fuente?. Los buenos equipos tienen un único script que al ejecutarlo se encarga de traer la última versión del código, recompilar cada línea, generar los ejecutables en todas sus versiones, idiomas y combinaciones de #ifdef, crear el paquete de instalación y almacenarlo en su soporte final (imagen de CD, sitio web para descargar, etc...).

Si este proceso se produce en más de un paso, es propenso a errores. Y cuanto más te acerques a la fecha de entrega más sentiras la necesidad de que el ciclo de corregir el último bug, construir los ejecutables, etc... sea lo más rápido posible. Si necesitas 20 pasos compilar el código, construir el instalador, etc... te volverás loco y empezarás a cometer errores tontos.

Por esta razón, en la última empresa en la que trabajé cambiaron de WISE a InstallShield: necesitábamos que el proceso de instalación pudiera ejecutarse desde un script, automáticamente, por la noche, usando el gestor de tareas de NT y con WISE no podíamos, así que lo desechamos. (Los amables colegas de WISE me han asegurado que la última versión ya permite hacer esto).

¿Compilas el producto diariamente?

Cuando usas control de versiones a veces un programador sube algo al servidor que acaba estropeando la compilación del producto. Por ejemplo, un programador añade un nuevo fichero fuente y todo compila perfectamente en su máquina, pero se le olvida subirlo al repositorio. Apaga el ordenador y se va feliz y tranquilo a casa. Sin embargo, gracias a eso, los demás no pueden seguir trabajando, así que también se tienen que ir casa, pero no tan contentos.

Estropear el proceso de compilación es tan malo (y tan frecuente) que viene bien compilar el producto diariamente para asegurarse de que este tipo de errores no pasan inadvertidos. En equipos grandes una buena forma de asegurarse de que un error de este tipo se corrige enseguida, es hacer una compilación diaria a la hora de comer, por ejemplo. Todo el mundo sube sus cambios en el código antes de comer. A la vuelta, la compilación ya ha terminado. Si todo ha ido bien, ¡enhorabuena!. Todo el mundo se baja la última versión del código fuente y continúa trabajando. Si la compilación falló, lo arreglas y ya está pero, mientras, todo el mundo puede seguir trabajando con la versión anterior del código (que sí que compilaba antes de subirlo).

En el equipo de Excel teníamos una regla: quien estropeara el proceso de compilación se tenía que encargar, como "castigo", de velar por el proceso de compilación hasta que otra persona lo volviera a estropear. Esto era un buen incentivo para no estropear el proceso de compilación, y una buena forma de ir rotando para encargarse de esta tarea y así aprender cómo funcionaba.

Puedes leer más sobre las compilaciones diarias en mi artículo: Daily Builds are Your Friend.

¿Tienes una base de datos para los bugs?

Me da igual lo que me cuentes. Si estás escribiendo código, incluso en un equipo de uno, vas a entregar un producto de baja calidad si no tienes una base de datos organizada donde registrar los bugs. Muchos programadores creen que pueden acordarse de memoria de los bugs pendientes por corregir. Chorradas. Yo no puedo acordarme de más de dos o tres a la vez y, a la mañana siguiente, con las prisas de la entrega, se me olvidan. Es indispensable que mantengas un registro formal de los bugs.

Una base de datos para registrar los bugs puede ser complicada o sencilla. Una base de datos de bugs mínimamente útil debe incluir la siguiente información sobre cada bug:

  1. Pasos específicos para reproducir el bug
  2. Comportamiento esperado
  3. Comportamiento (erróneo) observado
  4. A quién se le asigna ese bug (quién se hace responsable de él)
  5. Si está corregido o no

Si lo único que te está impidiendo registrar los bugs es la complejidad de los programas de seguimiento de bugs, basta con que hagas una tabla con cinco columnas para estos campos y empieces a utilizarla.

Más sobre seguimiento de bugs en Painless Bug Tracking.

¿Corriges los bugs antes de añadir más código?

La primera versión de Microsoft Word para Windows fue un infierno de proyecto. Costó una barbaridad. Cada vez tenía peor pinta. El equipo no paraba de trabajar, el proyecto se volvía a retrasar una y otra vez, y el nivel de estrés era increíble. Cuando por fin se comenzó a distribuir el producto, con años de retraso, Microsoft mandó de vacaciones a todo el equipo a Cancún y se hizo un serio análisis interior.

Lo que descubrieron fue que los jefes de proyecto habían insistido tanto en ajustarse a la "planificación" que los programadores apenas dedicaron tiempo al proceso de codificación, escribiendo un código nefasto porque la corrección de bugs no formaba parte de la planificación formal. No se intentó minimizar el número de bugs. Más bien al revés. Se cuenta que un programador que tenía que escribir el código para calcular la altura de una línea de texto, simplemente escribió "return 12;" y se quedo esperando al informe del bug que dijera que su función no era correcta para todos los casos. La planificación era simplemente una guía para ir convirtiendo los requisitos en bugs. En el post-mortem, a esto se lo denominó "metodología de infinitos defectos".

Para solucionar el problema, Microsoft adoptó globalmente algo así como una "metodología de cero defectos". Muchos de los programadores de la compañía se mofaron porque parecía que los jefes creían que iban a reducir el número de bugs por ley. En realidad, "cero defectos" significaba que, en todo momento, la prioridad máxima era corregir los bugs antes de empezar a escribir código nuevo. He aquí porqué.

En general, cuanto más se tarda en corregir un bug, más costoso (en tiempo y dinero) es corregirlo.

Por ejemplo, cuando cometes un error tipográfico o de sintaxis que detecta el compilador, arreglarlo es bastante trivial.

Cuando tienes un bug en tu código y lo ves la primera vez que lo ejecutas, apenas te costará tiempo corregirlo porque todavía tienes todo el código fresco en tu cabeza.

Si encuentras un bug en código que escribiste hace unos cuantos días te costará un rato encontrarlo pero, en cuanto vuelvas a ver el código que escribiste, te acordarás de todo y serás capaz de corregirlo en un tiempo razonable.

Pero si encuentras un bug en código que escribiste hace meses, seguramente habrás olvidado muchas cosas sobre ese código, y te costará bastante más arreglarlo. Para entonces igual te encuentras corrigiendo código de otra persona y puede que esté de vacaciones, en cuyo caso corregir el bug es como la ciencia: tienes que ser tranquilo, metódico, meticuloso y, aun así, no estás seguro de cuánto te costará encontrar la solución.

Y si descubres un bug en el código de un producto que ya está en la calle, corregirlo va a suponer un incremento de costes considerable.

Ésa es una de las razones por las que se debe corregir los bugs de forma inmediata: porque cuesta menos tiempo. Pero hay otra razón, relacionada con el hecho de que es más fácil predecir cuánto cuesta escribir código nuevo que corregir un bug existente. Por ejemplo, si te pidiera que me predijeses cuánto te costaría corregir ese bug donde tu código deja de funcionar si tienes instalado Internet Explorer 5.5, no tendrías ni idea, porque no sabes (por definición) qué es lo que causa el bug. Encontrarlo podría costar 3 días o 2 minutos.

Lo que todo esto nos enseña es que, si tienes una planificación con un montón de bugs por corregir, la planificación ya no es fiable. Pero si has corregido todos los bugs conocidos y todo lo que queda es escribir código nuevo, entonces tu planificación será bastante más precisa.

Otra cosa estupenda de intentar mantener el número de bugs a cero, es que puedes responder mucho más deprisa a la competencia. Algunos programadores les gusta verlo desde otro punto de vista: tener el producto listo para salir a la calle en cualquier momento. Así, si la competencia mete en su programa una funcionalidad cojonuda que te está haciendo perder clientes, puedes implementarla y sacar el producto de inmediato, sin tener que ponerte a corregir una larga lista de bugs que se han ido acumulando.

¿Tienes una planificación actualizada?

Lo cual nos lleva a hablar de planificaciones. Si tu código es importante para la empresa, hay muchas razones por las cuales es importante que la empresa sepa cuándo estará terminado el código. Los programadores suelen refunfuñar bastante a este respecto: "¡Estará terminado cuando esté terminado!", suelen responder a los comerciales.

Desafortunadamente, eso no acorta los plazos. Hay muchas decisiones respectivas a la planificación que la empresa tiene que tomar mucho antes de comercializar el producto: demos, ferias, anuncios, etc... Y la única forma de hacerlo es tener una planificación y mantenerla actualizada.

Otro tema crucial de tener una planificación es que te obliga a decidir qué funcionalidades vas a implementar para, finalmente, coger las menos importantes y eliminarlas, en vez de desviarse hacia la "featuritis" o "scope creep" (Nota del traductor: Esto es, ir cambiando los requisitos y añadiendo funcionalidades mientras se está construyendo un sistema).

Mantener las planificaciones no tiene que ser costoso. Lee mi artículo "Especificación funcional sin dolor" , que explica cómo hacer buenas planificaciones de manera sencilla.

¿Tienes un documento de especificaciones?

Tener las especificaciones reflejadas en un documento escrito es como pasarse la seda dental: todo el mundo está de acuerdo en que hay que hacerlo, pero nadie lo hace.

No estoy seguro de por qué pasa esto, pero probablemente es porque a la mayoría de los programadores no les gusta escribir documentación. En equipos de trabajo donde todos son programadores suele ocurrir que prefieren expresar su solución como código y no como documentación. Suelen lanzarse a escribir código en vez de redactar una especificación primero.

En la fase de diseño cuando descubres problemas puedes solucionarlos fácilmente cambiando unas cuantas líneas de texto. Sin embargo, una vez que el código ya está escrito el coste de solucionarlos se incrementa notablemente, tanto desde el punto de vista "emocional" (la gente odia tener que tirar código a la basura) como en tiempo, así que se suele ser bastante reacio a solucionar los problemas en esta fase. El software que no ha sido construido sobre un documento de especificaciones normalmente acaba estando mal diseñado y la planificación se va fuera de control. Parece que esto es lo que ocurrió con Netscape: las cuatro primeras versiones se acabaron convirtiendo en una chapuza tal que desde management se decidió estúpidamente tirar todo el código a la basura y empezar de nuevo. Y volvieron a repetir este error con Mozilla, creando un monstruo incontrolable que tardó varios años en alcanzar la fase alpha.

Mi teoría es que esto se puede solucionar enseñando a los programadores a que sean menos reacios a ser escritores enviándolos a un curso intensivo de escritura. Otra solución es contratar program managers inteligentes que generen documentos de especificaciones. En cualquier caso, deberías hacer cumplir la norma "nada de código sin especificación". Apréndelo todo sobre cómo escribir especificaciones en mis 4 artículos.

¿Están los programadores en un lugar tranquilo?

Está ampliamente documentado que se obtienen beneficios en productividad dando espacio, tranquilidad e intimidad a la gente cuyo trabajo es fundamentalmente intelectual. En Peopleware, el libro clásico sobre software management, se documentan extensamente todos estos beneficios en productividad.

He aquí el problema. Todos sabemos que quienes tienen un trabajo intelectual funcionan mejor una vez que han logrado meterse "en ambiente", cuando están totalmente concentrados en el trabajo y han logrado desconectar del entorno. Pierden la noción del tiempo y hacen un trabajo estupendo gracias a esa concentración absoluta. Es en estos momentos cuando hacen todo su trabajo productivo. Escritores, programadores, científicos e incluso jugadores de baloncesto nos podrían contar lo que es estar "en ambiente".

El primer problema es que meterse "en ambiente" no es fácil. Al intentar medirlo, parece que cuesta una media de 15 minutos empezar a trabajar a productividad máxima. A veces, si estás cansado o ya has hecho suficiente trabajo creativo ese día, simplemente no puedes volver a meterte en ambiente y te pasas el resto del día curioseando, por la web o jugando al Tetris.

El otro problema es que es muy fácil desconcentrarse. El ruido, las llamadas de teléfono, salir a comer o a tomar un café, las interrupciones de los compañeros (especialmente las interrupciones de los compañeros)... todo esto hace que te desconcentres. Si un compañero te pregunta algo y te interrumpe durante 1 minuto, pero esto es suficiente para te desconcentres y te cueste otra media hora volver a ser productivo, tu productividad global está en apuros. Si trabajas en un entorno ruidoso como el que les encanta crear a los tipos de las empresas .com, con los comerciales gritando al teléfono al lado de los programadores, la productividad caerá en picado conforme se va interrumpiendo a la gente que necesita estar "en ambiente" para trabajar.

Con los programadores esto es especialmente preocupante. La productividad depende de ser capaz de tratar con un montón de pequeños detalles a la vez, retenidos en nuestra memoria a corto plazo. Cualquier tipo de interrupción puede hacer que todos estos detalles se vayan al traste. Cuando continúas con el trabajo no puedes recordar ninguno de esos detalles (como el nombre de las variables locales que estabas utilizando o en qué punto te habías quedado implementando un algortimo de búsqueda) y tienes que volver a mirártelos, con lo cual tu trabajo se ralentiza hasta que vuelves de nuevo a trabajar a ritmo normal.

Veámoslo con números. Digamos (como parece demostrar la evidencia) que si interrumpimos a un programador, aunque sólo sea durante un minuto, en realidad le estamos quitando 15 minutos de productividad. Por poner un ejemplo, supongamos que tenemos dos programadores, llamados Jeff y Mutt, en cubículos uno al lado del otro como si fuera la típica granja para engordar ganado, estilo Dilbert. Mutt no se acuerda del nombre de la versión Unicode de la función strcpy. Podría buscarlo, que cuesta unos 30 segundos, o podría preguntarle a Jeff, que cuesta 15 segundos. Como está sentado al lado de Jeff, le pregunta a Jeff. Jeff se desconcentra y pierde 15 minutos de productividad (para ahorrarle 15 segundos a Mutt).

Ahora movámoslos a oficinas separadas, con puertas y paredes. Esa vez, cuando Mutt no se acuerde del nombre de la función, podría buscarlo, que sigue costando 30 segundos, o podría preguntárselo a Jeff, que ahora cuesta 45 segundos y hay que levantarse (¡lo cual no es fácil dada la baja forma en que suelen estar los programadores!). Así que lo busca. Esta vez Mutt pierde 30 segundos de productividad, pero le ahorra 15 minutos a Jeff. ¡Anda!.

¿Utilizas las mejores herramientas que puedes comprar?

Escribir código en un lenguaje compilado es una de las últimas cosas que todavía no se pueden hacer de forma inmediata en un ordenador. Si el proceso de compilación tarda más de un par de segundos, comprarte un ordenador mejor y más rápido te ahorrará mucho tiempo. Aunque la compilación tarde sólo 15 segundos, los programadores se aburrirán mientras el ordenador está ocupado compilando y se pondrán a leer The Onion, que los absorberá y acabará con horas de productividad.

Corregir código de interfaz de usuario con un sólo monitor es fastidioso, por no decir imposible. Si tienes que escribir código de interfaz de usuario, con dos monitores la cosa será mucho más fácil.

La mayoría de los programadores en algún momento tienen que manipular imágenes en formato bitmap para iconos o barras de herramientas, y la mayoría de los programadores no tienen un buen editor de bitmaps a su disposición. Tratar de usar Microsoft Paint para manipular bitmaps suena a chiste, pero eso es lo que la mayoría de los programadores acaban teniendo que hacer.

En mi último trabajo, el administrador de sistemas no paraba de enviarme spam de forma automática, quejándose de que estaba usando más de... atención... 220 megas de espacio en el disco del servidor. Le dije que, dado el precio de los discos duros actualmente, el coste de ese espacio estaba bastante por debajo del coste del papél higiénico que yo usaba. Dedicar aunque sólo fueran 10 minutos a limpiar mi directorio sería una pérdida de productividad enorme.

Los equipos de desarrollo de primer nivel no torturan a sus programadores. Incluso esas pequeñísimas frustraciones debidas a utilizar herramientas que no están a la altura se van acumulando poco a poco, haciendo que los programadores estén descontentos y se pongan de mal humor. Y un programador malhumorado es un programador improductivo.

A esto hay que añadir que... es fácil "sobornar" a los programadores poniendo a su disposición lo mejor y que esté a la última. ¡Y sale mucho más barato que pagarles sueldos competitivos!.

¿Tienes gente para probar los productos?

Si tu equipo no tiene gente dedicada en exclusiva a probar los productos, al menos uno por cada dos o tres programadores, o estás sacando a la calle productos llenos de fallos, o estás tirando el dinero teniendo a un programador que te sale a 100$ la hora haciendo un trabajo que podría hacer una persona dedicada a pruebas por 30$ la hora. Escatimar en gente para hacer pruebas es una falsa forma de ahorrar tan extravagante que sigo alucinando de que siga habiendo tal cantidad de gente que no se dé cuenta.

Léete Top Five (Wrong) Reasons You Don't Have Testers, un artículo que escribí sobre este tema.

¿Haces escribir código a los nuevos candidatos en las entrevistas?

¿Contratarías a un mago sin pedirle que te hiciera algunos trucos?. Claro que no.

¿Y a una empresa de catering para tu boda sin haber probado su comida?. Lo dudo. (A no ser que fuera la tía Marge, que te odiaría para siempre si no le dejaras hacer su "famoso" pastel de hígado).

Aun así, cada día, se sigue contratando a programadores basándose sólo en su impresionante currículum o porque el entrevistador se lo pasó bien charlando con él. O se les preguntan cosas sin ninguna importancia (como "¿cuál es la diferencia entre CreateDialog() y DialogBox()?") que se responden mirando la documentación. ¿Qué más da si se han aprendido de memoria millones de cosas sin importancia sobre programación?, lo que te importa es si son capaces de crear código. O, todavía peor, se les preguntan cosas del estilo "idea feliz": ese tipo de preguntas que parecen muy fáciles cuando ya te sabes la respuesta, pero que son imposibles de contestar si no te la sabes.

Por favor, deja ya de hacer esto. Haz lo que quieras en las entrevistas, pero haz que el candidato escriba algo de código. (Para más consejos, lee mi artículo Guerrilla Guide to Interviewing).

¿Haces pruebas de usabilidad "de vestíbulo"?

Una prueba de usabilidad "de vestíbulo" consiste en convencer a la primera persona que pase por la entrada para que se anime a utilizar el código que has escrito. Si haces esto con cinco personas, te enseñarán el 95% de lo que debes saber sobre los problemas de usabilidad de tu código.

Diseñar una buena interfaz de usuario no es tan dificil como crees, y es crucial si quieres que a los clientes les guste tu producto y lo compren. Puedes leer gratis mi libro online sobre diseño de interfaces gráficas, una pequeña introducción al tema para programadores.

Pero lo más importante sobre las interfaces de usuario es que, si enseñas tu programa a unas cuantas personas (con cinco o seis es suficiente), rápidamente descubrirás los problemas más importantes que encuentran. Léete el artículo de Jakob Nielsen explicando por qué. Aunque no sepas mucho sobre interfaces de usuario, mientras te obligues a hacer pruebas de usabilidad "de vestíbulo", que no cuestan nada, tu interfaz acabara siendo mucho, mucho mejor.

Cuatro formas de usar el Test de Joel

  1. Evalúa a tu propia empresa y dime qué puntuación obtiene, así puedo cotillear un rato.
  2. Si eres responsable de un equipo de programación, utilízalo como una guía para asegurarte de que el equipo trabaja lo mejor posible. Cuando obtengas un 12 como puntuación, puedes dejar en paz a tus programadores y dedicarte a tiempo completo a que los comerciales dejen de molestarlos.
  3. Si estás intentando decidir si aceptar una oferta de trabajo como programador, pregunta a tu futuro jefe qué puntuación obtendría la empresa en el test. Si te parece una puntuación muy baja, asegúrate de que tendrás autoridad suficiente para solucionar lo necesario. En caso contario, acabarás frustrándote y siendo poco productivo.
  4. Si eres un inversor que quiere evualuar a un equipo de programación, o si tu empresa está considerando la posibilidad de fusionarse con otra, este test puede servir para hacer una evaluación rápida.

The Joel on Software Translation Project - Español

Personal tools