Las mejores buenas prácticas para tener en cuenta en nuestro día a día

¿Cómo lograr una buena calidad de código y cobertura de test? ¿Qué podemos hacer para no caer en la monotonía? ¿Cómo cambiar la rutina por buenas prácticas? ¡Con este post vamos a intentar dar un pequeña receta para lograrlo!

Imaginemos una situación que suele ser habitual: estamos en un proyecto utilizando tecnologías que nos limitan bastante (por ejemplo, a pesar de ser un proyecto web con Java, no podemos usar Spring).

Por limitaciones del cliente, usamos la infraestructura (nada de locuras de contenedores ni cloud…) y procedimientos del cliente. Ante este panorama, ¿qué podíamos hacer?

A pesar de todo lo anterior hemos conseguido que en el resto de metodologías el proyecto sí destaque y esto nos ha permitido conseguir un producto final de buena calidad y que se sustenta sobre buenas prácticas como TDD, pair programming, code reviews, etc. ¡Vamos a repasarlas!

TDD 

Test Driven Development, ¿qué se esconde detrás de este concepto? Vamos a remontarnos a sus orígenes. 

Allá por 1996, cuando la antigua metodología informática dominaba el mundo, Kent Beck diseñó una nueva metodología que rompía con todo lo que había (por lo que se generó bastante controversia). 

Al final, el nuevo enfoque buscaba crear software de calidad y de la forma más productiva posible. Además tiene similitudes con Scrum (todas nos sonarán):

  • Desarrollo de ciclos cortos.
  • Entregas frecuentes.
  • Adaptación al cambio.
  • Nunca se compromete la calidad. 

Pero volviendo a lo que intentamos explicar, ¿qué es TDD? ¿cómo se hace? Es un proceso de desarrollo que consiste en codificar pruebas, desarrollar y refactorizar de forma continua el código construido.

La idea principal de esta metodología es realizar de forma inicial las pruebas unitarias para el código que tenemos que implementar, es decir, primero codificamos la prueba y, posteriormente, se desarrolla la lógica de negocio.

Podríamos imaginar el flujo de trabajo como que nuestro PO tiene un nuevo requisito:

  • Se escribe la historia de usuario que cumpla el nuevo requisito.
  • Se trabaja con la PO para buscar los criterios de aceptación más simples.
  • Cogemos un criterio de aceptación (cuanto más simples mejor) y hacemos la traducción a prueba unitaria.

Let’s Code!

  1. El test debe fallar al codificar el requisito.
  2. Se escribe el mínimo código que hace pasar la prueba.
  3. Se vuelven a pasar todas las pruebas automatizadas para comprobar que todo sigue funcionando (o la que estamos haciendo).
  4. Añadimos un nuevo requisito a nuestro test y volvemos al punto 3 hasta completar la historia de usuario.

Después de desarrollar qué ocurre:

  • Tenemos una gran cobertura de Test. Superior al 90% en la mayoría de casos.
  • Ya hemos codificado nuestro código, ¿funciona y ahora tenemos que escribir los test? ¡No! Ya están hechos y verifica que tu código funciona.
  • El código está orientado a requisitos (historias de usuario).
  • Aunque parezca más costoso, se produce software de mayor calidad y en menor tiempo
  • En algunos casos nos ahorra tener que estar debuggeando nuestro código.

Pair programming 

La programación por parejas es una de las prácticas que forman parte de extreme programming. Consiste en que dos personas se sienten frente a un ordenador y, mientras una de ella va programando, la otra va observando lo que desarrolla, analizándolo para poder aportar su opinión.

A la persona que se encarga de programar se le conoce como driver y a la persona que observa y analiza lo que hace el driver se le conoce como navigator. Estos dos roles no son fijos y deben de ir rotando para evitar la monotonía

Podrían darse dos situaciones respecto al nivel técnico de las dos personas involucradas, si el driver y el navigator tienen un nivel similar los dos aprenderán el uno del otro. Y si uno de los dos tiene un nivel notablemente superior al otro, el menos experimentado aprenderá del más veterano.

Como cualquier otra disciplina, la programación por parejas necesita de un tiempo en el cual las personas que lo emplean se acostumbren a esta forma de trabajar.

En esta disciplina, las tareas de corta duración se suelen ver ligeramente penalizadas pero el resto de ventajas como la reducción de errores y la eficiencia de las líneas de código se mantiene.

Donde realmente este sistema es ventajoso es en tareas con largos períodos, aquí es donde esa penalización del tiempo prácticamente desaparece.

A pesar de que la programación por parejas se pueda llevar a cabo con cualquier tarea sin importar su complejidad, donde realmente se aprovechan sus ventajas es en tareas con una cierta complejidad donde los dos programadores puedan aportar todos sus conocimientos. 

Ping pong programming

Code reviews

Una revisión de código (code review) es el proceso por el cual se revisa el código de otra persona en busca de errores o posibles mejoras. 

El motivo principal de la importancia de una buena revisión de código es que todos cometemos errores (o no hacemos las cosas todo lo óptimas que podrían ser) y que poder ver los propios errores es más difícil que los vea otra persona.

Las revisiones de código tiene varias ventajas:

  • Detección temprana de errores

Las revisiones de código deben hacerse una vez se ha desarrollado la funcionalidad para la que está destinada el código (con sus respectivas pruebas) y antes de que éste sea fusionado con la rama principal de nuestro software.

Gracias a ello podemos detectar errores no solo antes de que esté desplegado en un entorno productivo, sino antes de que forme parte de la rama principal de nuestro software. Esto disminuye el número de posibles errores y también la probabilidad de que haga falta una refactorización del código.

  • Detección de mala legibilidad del código

Bien sea por un descuido o por malas prácticas, es probable que escribamos un código que resulte difícil de leer para nuestros compañeros o para nosotros mismos en el futuro. 

Una pronta revisión de código nos permite darnos cuenta de estos fallos y subsanarlos de tal modo que nuestro código no solo sea correcto desde el punto de vista computacional, sino también desde el punto de vista humano.

  • Búsqueda de soluciones más eficientes a un problema

En informática no es muy común que solo haya una forma de resolver un problema y puede ser que la solución que decidamos implementar en nuestro software, aunque sea correcta desde el punto de vista computacional, no sea la más óptima. 

Las revisiones de código permiten conocer la opinión de un compañero y poner en común ideas para poder llegar a la mejor solución.

  • Descentralización del conocimiento

Un gran problema en los proyectos de desarrollo de software es el conocido como “bus factor”, es decir, ¿qué pasaría si a Antonio le atropellase un autobús? Si esto ocurriera y solo Antonio supiera de un determinado tema, tendríamos un problema. 

Las revisiones de código permiten que el conocimiento de cómo se ha desarrollado determinada funcionalidad no recaiga únicamente sobre una persona, sino que recaiga al menos en quién lo ha desarrollado y quién lo ha revisado.

  • Mejora en la estimación de tareas

Este punto es una consecuencia directa del punto anterior. Cuanta más gente sepa sobre un determinado aspecto, más fácil será estimar cuánto se tardará en resolver un error al conocer más gente la complejidad de este.

  • Aprendizaje recíproco

Al haber un intercambio de información entre el programador y el revisor se establece un aprendizaje mutuo, no importa que uno tenga más experiencia que otro.

  • Permite al programador dedicarse a otra tarea

Uno de los problemas inherentes a cualquier actividad en la que haya que estar dedicado al 100% es el agotamiento mental. Las revisiones de código permiten que el programador se “relaje” realizando otra tarea y su trabajo sea menos rutinario.

A pesar de las ventajas, siempre ronda la mente de quien critica las revisiones de código un único (falso) inconveniente, “se pierde mucho tiempo”. 

Hablamos de falso inconveniente porque si bien hay que dedicarle tiempo a las revisiones de código, no solo es tiempo que no se pierde, sino que es tiempo que se gana en otros aspectos como formación, pruebas y corrección de posibles errores posteriores.

A la hora de hacer una revisión de código se podría tener en cuenta las siguientes consideraciones:

  • Cuidado con hacer revisiones de código muy grandes

Según un estudio que hizo Smartbear sobre un equipo de desarrolladores de Cisco el tamaño óptimo (en líneas de código) está entre 200 y 400. Por encima de esta cantidad la capacidad del cerebro para percatarse de errores en el código disminuye.

  • Tomarse el tiempo necesario para revisar

A la hora de llevar a cabo una tarea para la que se necesita mucha concentración es necesario tomarse el tiempo que haga falta, es decir, el ratio líneas de código por minuto no debe de ser muy alto. 

En el estudio mencionado en el apartado anterior se puede comprobar que con un ratio superior a 500 líneas de código por hora el número de errores detectados se decrementa.

  • Pero tampoco invertir demasiado tiempo

Como cualquier tarea para la que debamos dedicarle un esfuerzo, cuando llevamos realizándola durante más de una hora nuestra eficacia cae, por lo que es bastante recomendable o bien hacer una pausa para descansar o bien no hacer una revisión de código que dure más de una hora.

  • Usar listas de comprobación

Una buena idea para que al revisor no se le olviden las cosas que debe mirar es hacer listas de comprobación en las que podrían figurar por ejemplo las siguientes preguntas:

  • ¿Hay algún error lógico que sea obvio? Por ejemplo alguna línea de código que sea inalcanzable por ningún flujo.
  • ¿Los nombres de las variables describen su funcionalidad? Se evita poner nombres del tipo “variable1”, “variable2”.
  • Con el código desarrollado, ¿se cubre toda la funcionalidad requerida?
  • ¿El nuevo código ha sido desarrollado conforme a las guías de estilo que esté siguiendo el equipo de desarrollo?

Caso real

A continuación vamos a ver un ejemplo de una revisión de código en nuestro proyecto.

Sobre esta merge request el revisor abrió 77 discusiones. No todas las discusiones tienen por qué tratar sobre temas “complejos”, una discusión puede ser simplemente una posible corrección en el nombre de una variable.

Experiencia

Al principio, como cualquier nueva disciplina que se intenta aprender, la aplicación de buenas prácticas en nuestro día a día tiene su curva de aprendizaje (cuesta como todo). 

Sería algo parecido a ‘reprogramarte la forma de trabajar’, pero según vas avanzando te vas dando cuenta del gran beneficio que se está aportando al proyecto y al equipo. 

En cuanto a tiempos, es una inversión a largo plazo, al principio avanzas más lento pero cuando se interiorizan estos procesos se ahorra mucho tiempo y es tiempo de recoger beneficios.

Otro aspecto muy importante a la hora de implementar estas metodologías en un proyecto es que se incrementa el atractivo del mismo para las personas que trabajan en él; se reduce drásticamente parte de la frustración asociadas a malas prácticas (propias y ajenas), la sensación de estar “quemado” por tener que tratar con (por ejemplo) código legado desaparece si se evita que este código legado sea de mala calidad.

Bibliografía

Foto de rmorenovillamayor

Me definiría como una persona muy curiosa, sobre todo de la cantidad de cosas que aún me quedan por aprender y descubrir. Empecé hace 5 años como desarrollador, actualmente trabajo en Paradigma con tecnologías cloud. Me encantan los retos y me gusta estar al tanto de las últimas novedades. Creo firmemente en el clean code y en la práctica de TDD.

Ver toda la actividad de Rubén Moreno

Escribe un comentario