Cuando se trata de la inspección de código, la gente tiende a centrarse en quién lo hace. Pero el desarrollador que escribió el código juega un papel tan importante en el proceso como el revisor. Casi no hay recomendaciones para preparar el código para su inspección, por lo que los autores a menudo cometen errores simplemente por ignorancia.
Este artículo recopila las mejores prácticas para participar en la inspección de código como autor. Cuando termine de leer, comenzará a enviar a los inspectores conjuntos de cambios tan perfectos que arderán de amor por usted, nada menos.
Pero no quiero que los inspectores de códigos brillen de amor por mí
Y lo seguirán siendo. Sé humilde. Nadie en la historia de la humanidad se ha quejado todavía en su lecho de muerte de que fue demasiado amado durante su vida.
¿Por qué mejorar la inspección de códigos?
Aprender técnicas de inspección efectivas le facilitará la vida al inspector, al equipo y, lo más importante, a usted.
- Proceso de transferencia de conocimiento acelerado. Si prepara su conjunto de cambios correctamente, la atención del inspector se centrará en las áreas en las que necesita crecer, en lugar de aburridas fallas estilísticas. Y cuando deja en claro que valora la crítica constructiva, el revisor comienza a esforzarse más en la retroalimentación.
- Un ejemplo para otros. Las buenas prácticas de inspección de código en su ejecución establecerán el estándar para quienes lo rodean. Generalmente se adoptan buenas técnicas, lo que significa que será más fácil para usted cuando alguien de sus colegas le envíe el código para su revisión.
- Conflictos mínimos. La inspección de códigos a menudo crea tensión en el equipo. Si aborda el asunto de manera responsable y deliberada, las disputas surgirán con menos frecuencia.
Regla de oro: valora el tiempo del revisor
Esto parece obvio, pero a menudo me encuentro con autores que tratan a los inspectores como sus especialistas personales en control de calidad. Estas personas no golpearán un dedo para detectar al menos algunos de los errores o para realizar una serie de cambios que sean convenientes para su verificación.
Sus colegas vienen a trabajar todos los días con una oferta limitada de atención. Si te dedican una parte, entonces ya no podrán gastar este recurso en sus propias tareas. Aprovechar al máximo su tiempo es una simple cuestión de justicia.
La revisión del código es mucho más exitosa cuando los participantes pueden confiar entre sí. Su inspector no escatimará esfuerzos si sabe que se tomará en serio sus comentarios. Si percibe al examinador como un obstáculo que debe superar, recibirá recomendaciones mucho menos valiosas de él.
Técnica
1.
Primero revise el código usted mismo. Antes de enviar el código a un colega, léalo. No se limite a detectar errores: imagine ver este fragmento por primera vez. ¿Qué puede ser confuso sobre esto?
En mi experiencia, puede ser útil tomar un descanso entre escribir y editar código. Las personas a menudo envían una parte nueva del código al final del día, pero es durante este período cuando es más probable que se pierdan algo por negligencia. Espere hasta la mañana, eche un vistazo al conjunto de cambios y luego páselo a un colega.
¿Qué idiota escribió eso?
Sincronización de los trabajos Cron con el ciclo lunar: agregué lógica sincronizada para mantener nuestra
tubería ETL en sintonía con la naturaleza. Simule el entorno de trabajo de un validador tanto como sea posible. Utilice la misma utilidad de comparación que utilizó él. Es mejor encontrar errores estúpidos en estas utilidades que en su editor de código habitual.
No espere ser perfecto. Inevitablemente, enviará el código con una pieza que olvidó eliminar después de corregir un error, o un archivo perdido que iba a eliminar. No es el fin del mundo, pero vale la pena seguirle la pista. Observe los patrones en sus errores y descubra qué sistemas puede implementar para prevenirlos. Si los mismos errores ocurren con mucha frecuencia, el inspector concluirá que usted no valora su tiempo.
2. Escribe una descripción clara del conjunto de cambios.
En mi último trabajo de mentor, tuve reuniones ocasionales con un programador más experimentado. Antes de la primera reunión, me pidió que tomara un documento de diseño de software que había compilado. Mientras le entregaba los papeles, le expliqué qué era el proyecto y cómo se relacionaba con los objetivos de mi equipo. Mi mentor frunció el ceño y dijo sin rodeos: "Todo lo que acaba de decir debe estar en la primera página del documento".
Y tenía razón. Escribí el documento con la expectativa de los desarrolladores de mi equipo, pero no tomé en cuenta que también podría ser leído por personas externas. La audiencia no se limitaba a los límites de mi departamento: todavía había equipos de socios, mentores, personas que tomaban decisiones sobre promociones.... El documento debería haberse redactado de modo que todo estuviera claro para ellos. Después de esta conversación, siempre trato de presentar mi trabajo en el contexto necesario para la comprensión.
La descripción del conjunto de cambios debe incluir cualquier información de fondo que el lector pueda necesitar. Incluso si está escribiendo una descripción para dirigirse al revisor, tenga en cuenta que puede tener menos información contextual de la que cree. Además, es posible que otros colegas también tengan que trabajar con este código en el futuro; al ver el historial de cambios, deben tener claras sus intenciones.
Una buena descripción describe para qué sirve el conjunto de cambios y por qué eligió hacerlo de esa manera.
Si desea profundizar en el arte de escribir excelentes descripciones, lea “ Cómo escribir un mensaje de confirmación de Git ” de Chris Beams y “ Mi confirmación de Git favorita ” de David Thompson.
3. Automatice cosas simples
Si confía en el inspector para cosas tan pequeñas como un aparato ortopédico flotante o problemas con las pruebas automatizadas, entonces está perdiendo su tiempo.
Compruebe si todo está en orden con la sintaxis. Recurriría al compilador, pero es una pena perder su tiempo.
Las pruebas automatizadas deben considerarse parte del procedimiento estándar como parte del equipo. La inspección comienza solo cuando se ha pasado toda la serie de comprobaciones automatizadas en un entorno de integración continua.
Si su equipo se engaña trágicamente y rechaza la integración continua, configure un pago automático en la empresa. Implemente enlaces, linters y formateadores previos a la confirmación en su entorno de desarrollo para garantizar que se sigan todas las convenciones y que el comportamiento previsto persista desde la confirmación hasta la confirmación.
4.Asegúrate de que el propio código responda a las preguntas.
Qué está mal con esta imagen?
No entiendo el propósito de la función.
Y esto es en caso de que se pase Frombobulator al llamar en ausencia de la implementación de frombobulate. El
autor me ayudó a descubrir la función, pero ¿qué pasa con el próximo lector? ¿Indagar en la historia de los cambios y releer todas las discusiones? Es aún peor cuando el autor se acerca a mi escritorio para explicarme todo en persona. En primer lugar, me impide concentrarme y, en segundo lugar, ya ningún alma viviente tendrá acceso a la información sonada.
Cuando un inspector expresa confusión sobre un punto del código, su trabajo no es aclarar la situación para esa persona en particular. Es necesario aclarar la situación para todos a la vez.
- ¿Hola?
- Cuando escribiste bill.py hace seis años, ¿por qué tenías t = 6?
- ¡Me alegro de que hayas llamado! Esto se debe al impuesto sobre las ventas del 6%.
- ¡Por supuesto!
- Una excelente manera de justificar una decisión de implementación.
La mejor respuesta a cualquier pregunta es la refactorización de código que la elimina. ¿Qué se puede renombrar para que quede más claro cómo cambiar la lógica? Los comentarios son una solución aceptable, pero definitivamente pierden en el contexto del código que, naturalmente, se documenta.
5. Ingrese los cambios fraccionalmente
Ampliar los límites es una mala práctica y, a menudo, se puede ver al inspeccionar el código. El desarrollador se compromete a corregir un error de lógica, pero en el camino se encuentra con una falla en la interfaz. "Bueno, ya que estoy trabajando con esta pieza de todos modos", piensa, "al mismo tiempo lo arreglaré". Como resultado, comienza la confusión. El revisor ahora tendrá que averiguar qué cambios funcionan para la tarea A y cuáles funcionan para la tarea B.
Los mejores conjuntos de cambios hacen una cosa . Cuanto más preciso y simple sea el cambio, más fácil será para el inspector tener en cuenta el contexto. Al compartir cambios no relacionados, también tiene la posibilidad de que varios pares revisen en paralelo, por lo que el código volverá a usted más rápido.
6.
Cambios funcionales y no funcionales separados Se sigue otra regla de la restricción de escala: los cambios funcionales y no funcionales no deben mezclarse.
Los desarrolladores con poca experiencia con la inspección de código a menudo rompen esta regla. Realizan algún tipo de cambio de desglose y el editor de código cambia inmediatamente el formato en todo el archivo. El desarrollador o no comprende lo que sucedió, o decide que esto es aún mejor, y envía el código, donde un cambio funcional está enterrado bajo cientos de líneas con otros no funcionales.
¿Encontrarás un cambio funcional?
Tal confusión es como un escupitajo en la cara de un inspector. Los cambios de solo formato son fáciles de verificar. También cambios funcionales. Una avería funcional en el océano de cambios de formato puede ser un desperdicio y una locura.
Además, a los desarrolladores les gusta mezclar la refactorización en cambios importantes de manera oportuna. Apruebo firmemente la refactorización de código por parte de los colegas, pero no cuando implementan simultáneamente nuevos comportamientos.
Cambio de comportamiento enterrado en medio de la refactorización
Si un fragmento de código necesita tanto refactorización como cambios de comportamiento, debe dividir el proceso en dos o tres conjuntos:
- Agregue pruebas para el comportamiento actual (si no hay ninguna)
- Refactorice el código sin cambiar nada en las pruebas
Al mantener las pruebas intactas en el segundo paso, el revisor puede asegurarse de que la refactorización no interrumpa el comportamiento. En consecuencia, en la tercera etapa, no tendrá que averiguar qué se está refactorizando aquí y qué funciona para cambiar el comportamiento; después de todo, separó uno del otro por adelantado.
7. Romper conjuntos de cambios que sean demasiado grandes Los
conjuntos de cambios hinchados son como los feos primos de los límites en expansión . Imagine una situación: un desarrollador llega a la conclusión de que para implementar la funcionalidad A primero tendrá que corregir la semántica de las bibliotecas B y C. Si hay pocos cambios, no importa qué, pero muy a menudo estas modificaciones se extienden y el resultado es una enorme lista de cambios.
La complejidad del registro de cambios crece exponencialmente con el número de filas afectadas. Si los cambios afectan a 400 líneas o más, busco una forma de dividirlas antes de solicitar una inspección.
¿Quizás en lugar de hacer todo a la vez, será posible trabajar primero con dependencias y, en el siguiente conjunto, implementar una nueva funcionalidad? ¿Es realista mantener el código sano si implementa la mitad de la funcionalidad ahora y la otra mitad en la siguiente fase?
Pensar en cómo dividir el código para conseguir una pieza inteligible y funcional puede resultar tedioso. Pero esto permite una mejor retroalimentación y crea menos complejidad para el revisor.
8. Acepte las críticas con amabilidad
La forma más segura de estropear toda la prueba es aceptar las críticas con hostilidad. Puede ser difícil resistirse, porque muchos desarrolladores se enorgullecen de lo que hacen y perciben su trabajo como una extensión de sí mismos. Y si el inspector hace comentarios sin tacto o va en persona , esto complica aún más el asunto.
En última instancia, usted, como autor, es libre de decidir cómo responder a los comentarios. Trate las palabras del inspector como una discusión objetiva del código que no tiene nada que ver con evaluar su personalidad. Si te pones a la defensiva, solo empeora.
Intento tomar cualquier comentario como un intento de ayudar y beneficiarme. Si el revisor encuentra un error estúpido en el código, instintivamente me siento atraído a empezar a poner excusas. Pero me contengo y alabo su observación en cambio.
- Para enero y febrero de 1900, no funcionará.
- ¡Exacto, bien notado!
Curiosamente, es una buena señal que el inspector encuentre fallas no evidentes en el código. Esto sugiere que es bueno preparando archivos para escanear. En ausencia de un formato descuidado, nombres incorrectos y otras cosas llamativas, el revisor puede profundizar en la lógica y el diseño y hacer observaciones más valiosas.
9. Sea paciente si el inspector comete un error
De vez en cuando sucede que el inspector simplemente se equivoca. Puede leer mal el código perfectamente normal y también puedes plantar errores. Muchos desarrolladores en tales casos comienzan a defenderse ferozmente. Les ofende que alguien esté criticando su trabajo, y ni siquiera se base en nada.
Sin embargo, aunque el revisor se equivoque, todavía tienes mucho en qué pensar. Si leyó mal algo, ¿cuál es la probabilidad de que otras personas cometan el mismo error en el futuro? ¿No tendrían los lectores que estudiar el código de un lado a otro, solo para asegurarse de que el error que ven no esté aquí?
- Aquí hay un desbordamiento de búfer, porque no se llevó a cabo ninguna verificación de si hay suficiente memoria en el nombre para acomodar todos los caracteres NewNameLen.
- ¿Está en mi código? ¡Inconcebible! El constructor llama a PurchaseHats y llama a CheckWeather, lo que arrojaría un error si la longitud del búfer no coincidiera. Primero leerías 200.000 líneas de código y luego te atreverías a admitir la posibilidad de que me equivoque en alguna parte.
Piense en cómo refactorizar, o agregue comentarios para que de un vistazo pueda comprender que todo está en orden aquí. Si el malentendido se debe al uso de características poco conocidas del lenguaje, vuelva a escribir el código utilizando mecanismos que no requieran un conocimiento profundo.
10. Da una reacción inteligible
A menudo me encuentro en esta situación: le envío comentarios a una persona, actualiza el código teniendo en cuenta algunos de ellos, pero al mismo tiempo permanece en silencio. Hay un período de incertidumbre. O se perdió el resto de los comentarios o todavía está en proceso de corrección. Si comienza a verificar lo que ya se ha hecho, hipotéticamente, puede resultar que este fragmento de código todavía está funcionando y estoy perdiendo el tiempo. Si esperamos, podemos entrar en un punto muerto: ambos nos sentaremos y esperaremos el siguiente paso el uno del otro.
Establece un cierto orden de acciones en el equipo para que siempre quede claro quién tiene la "batuta" en el momento. No se debe permitir que el proceso se ralentice solo porque nadie entiende lo que está sucediendo en absoluto. Esto es fácil de hacer, simplemente deje comentarios en el nivel del conjunto de cambios, a partir del cual está claro cuándo se transfiere el derecho a actuar a otro participante.
Corrigiendo los encabezados> Actualizando el código de acuerdo a los comentarios> Todo está listo, por favor mire.
Cualquier comentario que requiera que tome alguna acción debe ser respondido confirmando que lo ha tomado. Algunas herramientas de inspección de código ofrecen la posibilidad de marcar los comentarios procesados. Si no es así, use un conjunto de viñetas de texto simples como Listo. Si no está de acuerdo con el comentario, explique cortésmente por qué decidió abstenerse de corregir.
Algunas herramientas, como Reviewable y Gerritt, sugieren etiquetar los comentarios procesados
. Equilibre sus reacciones con el esfuerzo del revisor. Si ha detallado un momento para que puedas aprender algo nuevo por ti mismo, no te limites a la marca de “Hecho”. Responde pensativamente para demostrar que valoras su trabajo.
11. Solicite hábilmente la información faltante
A veces, los comentarios del inspector dejan demasiado espacio para la interpretación. Cuando te escriben algo con el espíritu de "No entiendo esta función", surge inmediatamente la pregunta, qué es exactamente lo que no está claro para una persona. ¿Demasiado largo? ¿Es el nombre desafortunado? ¿Necesitas documentar mejor?
Durante mucho tiempo me pregunté cómo aclarar los vagos comentarios y al mismo tiempo no entrar inadvertidamente en la confrontación. Lo primero que me vino a la cabeza fue preguntar: “¿Qué hay de incomprensible en ella?”, Pero suena malhumorado.
Una vez envié deliberadamente una respuesta vaga a este tipo de colega, y él me desarmó con su respuesta:
"¿Qué se puede cambiar para mejorarlo?"
Me gusta esta frase porque expresa apertura a la crítica y falta de hostilidad. Ahora, cuando recibo una retroalimentación vaga, respondo con alguna variación del motivo básico "¿Qué cambiar para mejorarlo?"
Otra técnica útil es intentar adivinar lo que quiso decir el revisor y tomar la iniciativa arreglando el código en consecuencia. Si recibe un comentario "incomprensible", mire más de cerca el código. Por lo general, se encuentra algo que se puede mejorar en términos de claridad. Las ediciones le permiten al inspector saber que está listo para realizar cambios, incluso si tenían una idea diferente del resultado final.
12. Dar prioridad al revisor
En el tenis, si no está del todo claro si la pelota salió fuera de límites al servir al oponente, se acostumbra interpretar la situación a su favor. Esta regla también debe seguirse al inspeccionar su código.
Algunas decisiones de diseño son cuestión de gustos. Si el revisor piensa que su función de diez líneas estaría mejor dividida en dos funciones de cinco líneas, la verdad objetiva no es ni suya ni suya. Qué opción es mejor depende de la preferencia.
Si el inspector hace una propuesta y los argumentos en apoyo de su posición son aproximadamente iguales para usted, acepte su punto de vista. Después de todo, de ustedes dos, él es quien se aprovecha de una nueva mirada al código.
13. Reducir el tiempo de transferencia de código
Hace unos meses, un usuario hizo un pequeño cambio en un proyecto de código abierto que mantengo. Me di de baja con comentarios unas horas después, pero ya desapareció con los finales. Unos días después volví y encontré que todavía no había respuesta.
Pasaron seis semanas y el misterioso desarrollador reapareció en el proyecto con revisiones. Aunque aprecio su trabajo, la larga pausa entre las dos etapas de verificación llevó al hecho de que dediqué el doble de esfuerzo a la inspección. Tuve que volver a leer no solo el código, sino también mis propios comentarios para recordar lo que se discutió en general. Si la persona se presentaba en un par de días, no habría necesidad de trabajo adicional.
Costos intelectuales para la inspección de códigos con tiempos de transmisión cortos (izquierda) y largos (derecha)
. Eje X - tiempo; eje y - memoria del inspector; sombreado azul - restauración del contexto; relleno azul - verificación de código; relleno gris - esperando; Sombreado rojo: costos adicionales
Seis semanas es, por supuesto, un caso excepcional, pero a menudo veo pausas largas e injustificadas en mi equipo. Alguien envía un conjunto de cambios para su revisión, recibe comentarios y pospone las ediciones durante una semana porque se distrajo con otra tarea.
Además de perder tiempo reconstruyendo el contexto, los fragmentos de código semiacabados crean complejidad. Hacen que sea más difícil hacer un seguimiento de lo que ya está drenado y lo que aún no lo está. Cuanto más parcialmente procesadas se generen las listas de cambios, mayor será la probabilidad de conflictos de fusión, y a nadie le gusta meterse con ellos.
Una vez que haya enviado su código para su inspección, su principal prioridad es seguir adelante. Si el proceso se detiene debido a su culpa, entonces le está robando tiempo al inspector y complicando la vida de todo el equipo.
Finalmente
Mientras prepara su próximo registro de cambios para enviarlo, considere qué factores puede abordar y utilice esas oportunidades para que la revisión sea productiva. Mientras participa en una revisión de código, compruebe si hay cosas que ralentizan el proceso y desperdician recursos con regularidad.
Recuerde la regla de oro: valore el tiempo del revisor. Si le da la oportunidad de concentrarse en las partes realmente interesantes del código, sus comentarios serán útiles. Si lo obligas a perder el tiempo en nimiedades o desenredar la confusión, tanto peor para los dos.
Finalmente, piense detenidamente en sus respuestas. Los malentendidos sobre trivialidades o palabras irreflexivas pueden hacer descarrilar las cosas con una velocidad alarmante. La pasión es alta cuando se trata de criticar el trabajo de otra persona, así que evite con cuidado cualquier cosa que pueda llevar al examinador a pensar que lo está atacando o que lo trata sin el debido respeto.
¡Felicidades! Si ha leído hasta aquí, es posible que ya se considere un experto en inspección de códigos. Lo más probable es que sus inspectores ya estén en llamas, por lo que los trata humanamente.