Code review: métodos y herramientas para revisar código
La revisión del código es una parte integral del desarrollo de software moderno. La revisión del código por parte de otros miembros del equipo de programación nos ayuda a descubrir errores y mejorar la calidad del código. Se utilizan diferentes herramientas, técnicas y enfoques que presentaremos con más detalle a continuación.
¿Qué es una revisión del código?
La revisión del código es una medida de garantía de calidad en el desarrollo de software. El código fuente es el medio básico del trabajo de desarrollo y el producto principal de la programación. El código recién creado o modificado se somete a una revisión del código. En este proceso, uno o varios miembros del equipo repasan el trabajo de un programador.
Un proyecto de software incluye una base de código o “codebase”: una colección de archivos de código que, en conjunto, sirven para entregar un producto. Incluye el código real del producto, la configuración, las herramientas de desarrollo, las pruebas y mucho más, todo mapeado en código. Todo el código base se gestiona con un sistema de control de versiones como Git. Se pueden gestionar varias versiones del código base en paralelo a través de varias “ramas”, por lo que permite avanzar en el desarrollo de nuevas funcionalidades sin cambiar la versión de producción del código base.
El trabajo de desarrollo suele tener lugar en las llamadas “Feature-Branch”, ramas que desarrollan características concretas y se integran periódicamente en la rama principal. La revisión del código se realiza antes de la “fusión”, es decir, antes de que el código nuevo o modificado se fusione con la base de código existente. El objetivo es detectar y eliminar los errores en una fase temprana antes de que el código pase a producción.
Pero la eliminación de errores no es el único beneficio de la revisión del código. Que el código funcione, es decir, que se ejecute sin errores y logre el resultado deseado, es solo un requisito básico. Además, hay una multitud de otros criterios de calidad para escribir código limpio o clean code. La presencia de comentarios, la claridad y coherencia del código, el cumplimiento de las directrices de estilo y que se integre correctamente en los sistemas existentes son aspectos críticos que se tienen en cuenta durante la revisión del código.
Dado que la mayor parte del trabajo de desarrollo se realiza en grupo, los efectos de la revisión del código van más allá de la pura calidad del mismo. Esto se debe a que la revisión del código la realizan otros miembros del equipo de desarrollo y genera efectos sociales: los nuevos miembros del equipo reciben información sobre convenciones y mejores prácticas, y el conocimiento se intercambia y distribuye dentro de la organización. De este modo, la revisión del código contribuye a fomentar una cultura de la calidad.
Aunque la revisión del código la realizan personas, hoy en día estos procesos suelen estar apoyados por las llamadas “code review tools”, herramientas especiales de revisión del código que crean eficiencia y liberan a las personas implicadas de la minuciosa coordinación de procesos, que requiere mucho tiempo. Esto permite que la gente se concentre en la revisión real del código.
Conceptualmente, la revisión humana del código se encuentra entre dos métodos de análisis automatizados, el análisis estático y el dinámico. Estas son las diferencias a simple vista:
Análisis estático | Revisión del código | Análisis dinámico |
Con herramientas automáticas | Por personas | Con herramientas automáticas |
El código se lee | El código se lee, la ejecución se reproduce mentalmente | El código se ejecuta |
Imponer un estilo coherente | Integrarse en el panorama general | Encontrar errores |
Errores tipográficos; vulnerabilidades y antipatrones conocidos | Vulnerabilidades de seguridad complejas; “code-smell” | Errores de integración; casos extremos raros; pruebas de carga |
¿Cómo funciona una revisión del código?
El concepto de revisión del código es sencillo: uno o varios miembros del equipo de desarrollo (llamados revisores o "reviewers") comprueban la corrección del código modificado o recién escrito. Los revisores leen el código e identifican posibles errores y desviaciones de las convenciones establecidas en el equipo. Los revisores mejoran el código a posteriori o transmiten sus conclusiones a los autores originales que incorporan los cambios.
Aunque la idea es sencilla, en la práctica, el esfuerzo de los procesos de revisión del código aumenta rápidamente y las pequeñas cosas se vuelven complicadas: ¿qué cambios van juntos y cómo se comunican a los revisores? ¿Cómo se asignan los errores y comentarios encontrados a los lugares apropiados del código y se ponen a disposición de los responsables de la mejora? Sin herramientas especiales de revisión de código, esto solo puede coordinarse en equipos muy pequeños.
En los equipos de programación ágiles y distribuidos, la revisión del código suele ser una parte integral del proceso de desarrollo. En el contexto de la integración continua, llamada en inglés “continuous-integration” o CI, el código se escribe, se prueba y se mantiene continuamente en la base de código existente. La revisión del código por parte de una persona forma parte de la cadena de producción automatizada por la que pasa cada unidad de código. El código se integra y posteriormente se traslada a los sistemas de producción, solo si se superan todas las pruebas.
Echemos un vistazo a los pasos individuales de un canal de integración continua o “pipeline de CI” y la posición que la revisión de código tiene en ella:
- Escribir el código
- Escribir código en la Feature-Branch
- Probar el código en el entorno local
- Integrar el código en la base de código
- Analizar y formatear automáticamente el código en la rama de características
- Realizar la revisión del código e incorporar mejoras
- Combinar el código en la rama principal o “main”
- Reproducir y probar la rama principal en área de pruebas o staging
- Poner el código en producción
- Combinar el código en la rama auxiliar completa o de release
- Reproducir la rama de release en “live-site”
¿Por qué es importante la revisión del código?
La revisión del código es una parte importante del control de calidad en el desarrollo de software, garantiza que el código recién escrito esté lo más libre de errores posible y cumpla con los estándares de calidad de la organización. A largo plazo, esto minimiza deuda técnica; a corto plazo, evita que se ejecute código defectuoso en los sistemas de producción.
El código es un medio poderoso; una vez escrito, el mismo código se ejecuta una y otra vez o simultáneamente como múltiples instancias. Así, los errores provocan un “efecto dominó”, en el que pequeños errores en un punto central tienen un gran impacto en todo el sistema. Suele ser mucho más costoso corregir los errores en el código que ya se está ejecutando en el sistema de producción que corregirlos de antemano.
La revisión del código ayuda a igualar las diferencias de calidad entre las distintas partes de la base de código. Esto se debe a que la calidad del código varía mucho en función de las circunstancias en las que se escribió el código. Estos factores disminuyen la calidad del desarrollo del código de un programador:
- Falta de experiencia en programación
- Poco conocimiento del sistema
- Falta de familiaridad con las convenciones del equipo
- Estrés durante el desarrollo
- Desarrollo bajo presión de tiempo
- Agotamiento mental
Hoy en día, el uso del código va más allá de la escritura de programas. El código es un medio expresivo que puede utilizarse para describir con precisión todo tipo de sistemas. Por ejemplo, el código se utiliza para realizar contratos inteligentes basados en la cadena de bloques o para definir entornos en la nube a través de la infraestructura como código. Para estos enfoques también puede entrar en juego una revisión del código.
¿Cuáles son las “best practices” para revisar código?
Las “best practices” presentadas aquí provienen de un amplio estudio empírico de un equipo de programación de Cisco realizado por Smart Bear. En parte, las “best practices” tienen en cuenta las limitaciones de los revisores humanos. El código es un medio complejo que requiere mucha atención para su revisión. El ser humano tiene una capacidad mental limitada que se agota con el esfuerzo continuo y, si no prestamos atención, pasamos por alto errores con facilidad y perdemos tiempo dedicado a la revisión del código.
Además, las “best practices” buscan garantizar que los procesos de revisión del código estén orientados a los objetivos. Si encontramos errores, también tenemos que corregirlos. Esto requiere responsabilidades claras y formas de gestionar los procesos y supervisar el progreso. Veamos las “best practices” que hemos encontrado:
- Comprobar un máximo de 400 líneas de código por sesión: con grandes cantidades de código, pasamos por alto errores fácilmente.
- En caso de revisiones rápidas, limitarse a menos de 500 líneas de código por hora: de lo contrario, la capacidad de los revisores para detectar errores se resiente.
- Limitar las revisiones de código a un máximo de 60 minutos: con las revisiones de código más largas, los revisores pierden la concentración necesaria.
- Establecer objetivos y contabilizar eventos: ¿cuántos errores se encuentran por unidad de tiempo o por línea de código?
- Los autores del código deben anotar el código fuente antes de la revisión: las anotaciones guían a los revisores a través de los cambios en el código, y los explican.
- Utilizar listas de control: estas deben contener los puntos que se observan durante cada revisión.
- Establecer un proceso para corregir los errores que se encuentren: no basta con detectar los errores. Para corregir los errores, se necesitan directrices y estructuras claras.
- Promover una cultura positiva de revisión del código: los errores no deben presentarse como un fallo personal, sino como una oportunidad para aprender.
- Utilizar las implicaciones subconscientes del proceso de revisión: si se sabe que el código está sujeto a revisión, los programadores se esfuerzan más.
- Apoyarse en procesos de revisión de código ligeros: las herramientas modernas de revisión del código han hecho que la revisión del código sea eficiente.
¿Cuáles son las ventajas y desventajas de las revisiones de código?
En general, la revisión del código se considera una parte esencial del desarrollo de software. Y es que las ventajas de estos procesos son evidentes. Sin embargo, también hay algunas desventajas derivadas de su uso. Veamos las ventajas e inconvenientes de la revisión del código.
Ventajas de la revisión del código
La principal ventaja de la revisión del código es detectar y corregir los errores con antelación, antes de que causen consecuencias negativas. Esto es mucho más eficaz que detectar y corregir los errores en un momento posterior del ciclo de vida del código. Si el código defectuoso ya forma parte de un sistema de producción, otros componentes pueden basarse en él, dificultando las mejoras.
Pero los beneficios de las revisiones periódicas del código van más allá de la búsqueda de errores individuales. En particular, también es importante observar el proyecto en su conjunto: ¿cómo encaja el código en la base de código? Las revisiones continuas del código ayudan a identificar patrones generales y a establecer normas. Además de los errores funcionales, se identifican y abordan code smells. Si es necesario, se usa la refactorización y patrones de diseño para crear homogeneidad en múltiples componentes.
Las revisiones de código involucran a los miembros del equipo de programación y fomentan el diálogo. No es de extrañar que los procesos de revisión de código establecidos ayuden a aumentar las habilidades de codificación del equipo. Las revisiones de código aglutinan y distribuyen el conocimiento en el equipo y mejoran las habilidades de código de sus miembros.
A nivel organizativo, las revisiones de código ayudan a establecer una cultura de la calidad. Si se sabe que se está revisando el propio trabajo, la gente tiende a esforzarse más. Para lograr el efecto positivo, basta con someter a un tercio del código producido a una revisión del mismo.
Desventajas de la revisión del código
Por supuesto, una revisión del código supone un mayor esfuerzo para la organización. La revisión del código cuesta tiempo e inmoviliza al personal, y se necesitan recursos para gestionar los procesos implicados. Sin embargo, los costes incurridos sirven para aumentar la calidad del código. No hay que olvidar que la mala calidad del código provoca costes considerables.
Sin “code review tools”, es decir, sin herramientas de apoyo para la revisión del código, puede ser muy ineficiente. Esto era especialmente problemático con los métodos tradicionales antes de que se popularizara la revisión ligera del código. En cualquier caso, se necesitan metas y objetivos claros para los procesos de revisión del código. Esto hace que el esfuerzo y el beneficio sean calculables y también evita los estados de limbo.
Por parte de los desarrolladores, las revisiones de código deberían suponer un aumento de los conocimientos y de la cohesión del equipo. Para ello es importante promover un entorno de trabajo constructivo y respetuoso. Si hay hostilidad o se culpabiliza durante una revisión del código, puede tener un efecto negativo en los implicados. Los recién llegados al equipo, los miembros de minorías y los programadores relativamente inexpertos se ven especialmente afectados por esto.
¿Qué tipos de revisión de código existen?
La primera forma de revisión del código se conocía como “inspección de Fagan”. Se trata de un proceso complejo que requiere cuatro personas e implica la impresión del código en papel, además de varias reuniones. Aunque es eficaz para encontrar errores, la inspección de Fagan es imposible de integrar en el trabajo de desarrollo ágil moderno.
En contraste con la engorrosa revisión de código de Fagan, hoy en día se utilizan enfoques ligeros. En todos ellos participan el autor o los autores del código y uno o varios revisores.
Método de revisión del código | Número de revisores | Ventajas | Desventajas |
Por encima del hombro | 1 | Fácil de coordinar | Los resultados pueden ser difíciles de controlar |
Programación en pareja | 2 | Máxima calidad del código | Requiere altas capacidades profesionales y personales |
Resumen por correo electrónico | Varios | Proceso relativamente sencillo | Puede llevar demasiado tiempo sin herramientas |
Con ayuda de herramientas | 1 a varios | Máximo nivel de eficiencia | Requiere herramientas |
Revisión del código “por encima del hombro”
El método “por encima del hombro” es la forma más sencilla de revisión del código. El autor presenta el código escrito a otro miembro del equipo de desarrollo (revisor). Además de buscar errores, se discuten las estructuras del código y se explican enfoques alternativos. La comunicación directa entre el presentador y el revisor permite una retroalimentación rápida y la incorporación inmediata de mejoras.
La revisión del código “por encima del hombro” tiene lugar en el propio ordenador. Quien revisa mira el código por encima del hombro mientras quien lo escribió hace la presentación. Esto permite el uso de todos los recursos y herramientas en la máquina de desarrollo. Una revisión del código “por encima del hombro” no es complicada y puede realizarse de forma puntual.
Revisión del código mediante pair programming
Conceptualmente similar a la revisión de código “por encima del hombro” es la revisión de código por pair programming. Una vez más, dos miembros del equipo de programación están involucrados. La diferencia radica en cuándo tienen lugar los procesos de creación y revisión del código. Mientras que la revisión del código “por encima del hombro” tiene lugar después de la creación del código, en el pair programming ambos procesos están entrelazados.
Durante el pair programming, una persona, conocida como controlador o “Driver”, escribe el código y se encarga de los detalles de la implementación. La otra persona, conocida como el navegador o “Reviewer”, supervisa el código escrito y proporciona comentarios. El navegador también tiene en cuenta el proyecto en su conjunto; el código no solo debe estar libre de errores y funcionar por sí mismo, sino que también debe seguir los patrones y reglas de todo el código involucrado.
Es importante que el controlador y el navegador intercambien regularmente sus papeles. De este modo, se produce una alternancia de perspectivas, que equilibra la balanza de poder y da a ambas personas la oportunidad de recuperarse mentalmente. Además, el participante con menos experiencia tiene la oportunidad de aprender en ambos papeles.
Revisión del código mediante un resumen por correo electrónico
Los cambios o nuevas adiciones de código en proyectos más grandes suelen requerir una revisión del código por parte de varias personas. La revisión del código mediante resumen por correo electrónico consiste en enviar un resumen de los cambios a todos los implicados. A continuación, se realizan varias rondas de debate por correo electrónico y se incorporan los cambios hasta que se completa la revisión para finalizar el código.
Como es fácil imaginar, el proceso puede volverse rápidamente confuso con un gran número de contribuyentes. Por lo tanto, la revisión del código a través de rondas de correo electrónico funciona mejor con el apoyo de herramientas adecuadas.
Revisión del código con ayuda de herramientas
Los enfoques modernos de la revisión del código utilizan herramientas especiales. Estas estructuran los procesos de revisión, aumentan la eficiencia y recogen métricas. Las herramientas hacen que el proceso de revisión sea planificable, controlable y verificable.
Existe una amplia gama de herramientas de revisión de código. Algunos de ellos se integran en los enfoques existentes para la integración continua o continuous delivery (CI/CD). Presentamos los diferentes tipos de herramientas junto con ejemplos.
¿Qué herramientas de revisión de código existen?
Los sistemas de control de versiones distribuidos (DVCS) y, en particular, el omnipresente Git, constituyen la base de las herramientas de revisión de código. Incluyen la funcionalidad de rastrear los cambios en el código y hacerlos visibles como “diffs”. Las plataformas construidas sobre Git, como GitHub y GitLab, mejoran la visibilidad y hacen hincapié en el trabajo en equipo. Con sus solicitudes de fusión, estas plataformas ofrecen una revisión integrada del código antes de aceptarlo.
Aprende a usar GitLab con nuestro tutorial de GitLab.
Herramientas de revisión de código basadas en DVCS
Estas herramientas utilizan como base Git u otro sistema de control de versiones distribuidos (DVCS). A partir de ahí, se suele utilizar una interfaz de usuario basada en la web para organizar las revisiones del código en el equipo. Algunas herramientas de revisión de código también tienen su propia interfaz de línea de comandos (CLI).
GitHub
GitHub se ha establecido como la plataforma estándar para la administración en la web de repositorios Git. El mecanismo principal para la revisión del código son las llamadas pull requests: si quieres hacer cambios en el código de un repositorio, sigue un esquema sencillo:
- Clonar el repositorio como copia local
- Realizar cambios en tu propia rama
- Crear un pull request: pide a los mantenedores del repositorio que comprueben los cambios y, si son positivos, los fusionen con el repositorio principal.
Review board
La herramienta de revisión de código Review Board pone en primer plano las solicitudes de revisión. Su moderna y amigable interfaz web proporciona una visión general de todas las solicitudes de revisión en curso en los repositorios y ramas. El comando dedicado rbt permite un acceso rápido desde la línea de comandos. Además del código, también puedes incluir gráficos y documentos PDF en los procesos de revisión.
Gerrit
Gerrit se instala en tu servidor y actúa como interfaz entre los cambios en el código y la base de código de producción. Mediante la revisión de código se supervisan los cambios y solo pasan a producción si son aprobados. Una instalación de Gerrit incluye un entorno Git autoalojado con acceso SSH y una interfaz basada en la web disponible a través de HTTPS. Además de las notificaciones opcionales por correo electrónico, Gerrit incluye un sistema para votar por los cambios en el código.
Code Collaborator
La herramienta de revisión de código Code Collaborator de Smart Bear pone en primer plano las historias o “Stories” de los usuarios. Se trata de especificaciones de funcionalidad centradas en el usuario que se traducen en el código y se validan mediante pruebas. La herramienta involucra al equipo de programación, a los gestores y a los equipos de pruebas, y permite una revisión coherente de los cambios en las historias de usuario, el código y los planes de pruebas.
Herramientas para preparar la revisión del código
Estas herramientas, conocidas como “linters”, se utilizan para analizar y dar formato automáticamente al código en preparación para la revisión del mismo. Técnicamente, se trata de un análisis estático porque el código se lee, pero no se ejecuta. Los linters se utilizan como parte del canal CI para estandarizar el formato del código o para adaptar el código a las especificaciones de estilo.
Este análisis estático también proporciona métricas de código, como el número de líneas de código (LOC) por archivo, clase o función. Los linters también pueden detectar errores comunes antes de la revisión humana del código. Entre ellos se encuentran los errores de escritura, las inyecciones SQL y los errores fuera de límites.
Herramientas para el desarrollo colaborativo en tiempo real
Estas herramientas relativamente nuevas funcionan conceptualmente como un editor de código basado en la web con sincronización de los cambios entre varios usuarios. Permiten la programación por parejas en entornos distribuidos y la revisión del código “por encima del hombro” sin importar dónde estén geográficamente los colaboradores. A raíz de la pandemia causada por COVID, estas herramientas se han hecho muy populares.
Tanto Replit como LiveShare integrado en el editor VSCode de Microsoft pueden utilizarse como editores HTML colaborativos. Ambas herramientas pueden manejar otros lenguajes y permiten el trabajo colaborativo con múltiples archivos e incluso la ejecución de código.