¿Qué haces cuando la revisión de código es demasiado difícil?

144

OK, entonces mucha revisión de código es bastante rutinaria. Pero ocasionalmente hay cambios que afectan ampliamente el código complejo y frágil existente. En esta situación, la cantidad de tiempo que llevaría verificar la seguridad de los cambios, la ausencia de regresión, etc. es excesiva. Quizás incluso excediendo el tiempo que llevó hacer el desarrollo en sí.

¿Qué hacer en esta situación? ¿Combinar y esperar que nada se escape? (¡No lo defiendo!) ¿Puede hacer lo mejor que pueda e intente solo detectar cualquier falla obvia (tal vez esta sea la mayor revisión de código a la que debe apuntar de todos modos?)

Esto no es específicamente una cuestión de si las pruebas deben realizarse como parte de una revisión de código. Esta es una pregunta que pregunta cuáles son las mejores opciones en la situación descrita, especialmente con una fecha límite apremiante, no hay un conjunto completo de pruebas unitarias disponibles o pruebas unitarias no viables para el código fragmentado que ha cambiado.

EDITAR: Tengo la impresión de que algunas de las respuestas / comentarios hasta ahora han captado mi frase "impacto general", y posiblemente consideró que el cambio implicó una gran cantidad de líneas de código. Puedo entender que esta sea la interpretación, pero esa no era realmente mi intención. Por "impacto general", quiero decir, por ejemplo, el potencial de regresión es alto debido a la interconexión de la base de código, o el alcance de los efectos secundarios, no necesariamente que el cambio en sí sea grande. Por ejemplo, un desarrollador puede encontrar una manera de corregir un error con una sola línea llamando a una rutina de alto nivel existente que conecta en cascada las llamadas a muchas rutinas de nivel inferior. Probar y verificar que la corrección de errores funcionó es fácil. Validar manualmente (mediante revisión de código) el impacto de todos los efectos secundarios es mucho más difícil.

Brad Thomas
fuente
9191
¿Qué pasa con la ejecución de su conjunto de pruebas para asegurarse de no romper nada?
Vincent Savard
130
what if there is no pre-existing test suite?- ¿Qué tal escribir uno?
Robert Harvey
27
El conjunto de pruebas definitivamente ayudaría. Pero la revisión por pares y las pruebas son complementarias. Creo que no es una buena idea reemplazar uno por el otro.
Christophe
8
@MasonWheeler: Probablemente una conversación para otro momento, y te refieres a TDD específicamente en ese artículo, usando suposiciones que no creo que ningún TDD'er respetuoso pueda hacer, pero lo he hecho de ambas maneras, y considero que los beneficios de las pruebas unitarias son evidentes.
Robert Harvey
21
Merge and hope nothing slips through?Esa es una idea notoriamente mala.
Mástil

Respuestas:

306

La premisa de la pregunta es, francamente, asombrosa. Suponemos que hay un gran cambio en el código complejo y frágil, y que simplemente no hay tiempo suficiente para revisarlo correctamente . ¡Este es el último código que debería dedicar menos tiempo a revisar! Esta pregunta indica que tiene problemas estructurales no solo en su propio código, sino también en su metodología de gestión del cambio.

Entonces, ¿cómo lidiar con esta situación? Comience por no entrar en él en primer lugar:

  • Identifique las fuentes de complejidad y aplique refactorizaciones correctas, cuidadosamente revisadas y correctas para aumentar el nivel de abstracción. El código debe ser entendible por un nuevo empleado recién salido de la universidad que sepa algo sobre su dominio comercial.

  • Identificar fuentes de fragilidad; Esto podría ser mediante la revisión del código en sí, examinando el historial de correcciones de errores en el código, y así sucesivamente. Determine qué subsistemas son frágiles y haga que sean más robustos . Añadir lógica de depuración. Añadir afirmaciones. Cree una implementación lenta pero obviamente correcta del mismo algoritmo y en su compilación de depuración, ejecute ambos y verifique que estén de acuerdo. En su compilación de depuración, haga que ocurran situaciones raras con más frecuencia. (Por ejemplo, cree un asignador de memoria que siempre mueva un bloque en la reasignación, o siempre asigne un bloque al final de una página, o lo que sea). Haga que el código sea robusto ante los cambios en su contexto. Ahora ya no tienes código frágil; ahora tiene un código que encuentra los errores, en lugar de causarlos.

  • Escribe un conjunto de pruebas automatizadas. Obviamente.

  • No hagas grandes cambios. Realice una serie de cambios pequeños y específicos, cada uno de los cuales puede verse como correcto.

Pero fundamentalmente, su escenario es "nos hemos metido en un agujero de deuda técnica y cada cambio complejo y no revisado nos profundiza más, ¿qué debemos hacer?". ¿Qué haces cuando te encuentras en ese agujero? Deja de cavar . Si tiene tanta deuda que no puede realizar tareas básicas como revisar el código del otro, entonces debe dejar de endeudarse más y dedicar tiempo a pagarla.

Eric Lippert
fuente
74
Por lo que he visto en la industria, "Detener la excavación" generalmente es seguido por una terminación rápida, seguida de encontrar a alguien que esté dispuesto a usar la pala. Esta respuesta debería agregar un descargo de responsabilidad de que los peones de mono código no deberían intentar esto sin estar preparados para las consecuencias ...
Luke A. Leber
63
@Luke si la gerencia o los desarrolladores senior están dispuestos a seguir adelante a pesar de los problemas, e incluso pensarán en terminar con cualquiera que intente poner algo de cordura a esta situación (OK, descartando la insubordinación descarada), la compañía está en una marcha de la muerte irreversible. Déjalos a él.
Julia Hayward
14
@JuliaHayward Tienes razón, pero aún así, la situación que describe Luke es común, especialmente en el código que ya está generando ingresos. Realmente depende de ti si vale la pena seguir trabajando en ello.
Owen
19
@ LukeA.Leber Tienes razón. He trabajado para estas empresas. Lo que sí puedo decirte es que la marcha de la muerte tardará años en completarse, pero cada mes empeorará progresivamente. Los 'Code Monkeys' serán más miserables cada mes, pero les tomará años a los malos gerentes darse cuenta de las consecuencias de sus acciones ... si es que alguna vez lo hacen.
JS.
10
@Matt: la suposición de la pregunta es que alguien se preocupa lo suficiente por la calidad del código como para tener un sistema formal de revisión de código, y que la persona que hace la pregunta está preocupada por el impacto de grandes cambios en la calidad del código. Si afirmamos que a nadie le importa la calidad del código, entonces, mi respuesta sobre las formas de garantizar la calidad del código no se aplica, ¡pero esa no es la pregunta que se hizo!
Eric Lippert
96

Uno del principal objetivo de una revisión de código es aumentar la calidad y entregar código robusto . Robusto, porque 4 ojos generalmente detectan más problemas que 2. Y el revisor que no ha escrito el código adicional tiene más probabilidades de cuestionar suposiciones (potencialmente incorrectas).

Evitar las revisiones por pares en su caso solo contribuiría a aumentar la fragilidad de su código. Por supuesto, reforzar las pruebas con un conjunto de pruebas sólido y repetible sin duda podría mejorar la calidad. Pero debería ser complementario a la revisión por pares, no un reemplazo .

Creo que la complejidad debe entenderse y dominarse, y la revisión por pares completa es la ocasión para compartir conocimientos y lograr esto. La inversión que realice para que más personas comprendan la fortaleza y la debilidad del código frágil ayudará a mejorarlo con el tiempo.

Una cita para concluir:

"Si quieres ir rápido, ve solo. Si quieres llegar lejos, ve juntos"

Christophe
fuente
55
De hecho, imagínese si 'complejo' se reemplazara por 'largo' o 'mal diseñado' o 'mal documentado' o cualquier otra característica negativa que diríamos "Esa no es una buena razón para revisar, ¡solucionemos esos problemas para que sea revisable! " Y esto no es diferente.
corsiKa
11
También agregaría que si el código no se puede revisar en este momento, no se puede mantener dentro de 6 meses .....
corsiKa
3
@corsiKa ¿Por qué esperar 6 meses para que no se pueda mantener?
krillgar
2
@krillgar Es umm ... no ... ese es solo un número que saqué de la parte superior de mi cabeza para representar un período de tiempo entre el momento en que estableciste el código y tuve que volver a recogerlo ... entonces, sí ...
corsiKa
16
@krillgar: Escribo un "nuevo código", lo reviso, voy a almorzar y cuando regreso, mi "nuevo código" se ha convertido mágicamente en "código heredado". ¿Cómo sucedió eso? :)
Eric Lippert
35

Bienvenido al mundo del desarrollo de software heredado.

Tiene cientos de miles, millones, 10 millones de líneas de código.

Estas líneas de código son valiosas, ya que producen un flujo de ingresos y su reemplazo es inviable.

Su modelo de negocio se basa en aprovechar esa base de código. Entonces, su equipo es pequeño, la base del código es grande. Es necesario agregar funciones para que las personas compren una nueva versión de su código o para que los clientes existentes estén contentos.

En un mundo perfecto, su enorme base de código está probada en el wazoo. No vives en un mundo perfecto.

En un mundo menos perfecto, tiene el presupuesto para arreglar su deuda técnica: desglosar su código en partes comprobables por unidad, realizar pruebas de integración exhaustivas e iterar.

Esto, sin embargo, está pagando deudas sin producir nuevas características. Lo que no coincide con el caso de negocio de "cosechar beneficios del código existente, mientras lo modifica para generar incentivos para actualizar".

Puede tomar grandes porciones de código y reescribirlo utilizando técnicas más modernas. Pero donde quiera que interactúe con el código existente expondrá posibles puntos de ruptura. Ese truco en el sistema del que se libró en realidad compensó una peculiaridad en un subsistema que no reescribió. Siempre.

Lo que puedes hacer es actuar con cuidado. Puede encontrar alguna parte del código que realmente comprende y cuyo comportamiento e interacción con el resto del sistema se entiende bien. Puede modernizar eso, agregando pruebas unitarias y haciendo su comportamiento aún más claro.

Luego, busca las partes del resto de la aplicación que interactúan principalmente con ella y ataca una por una.

Al hacerlo, puede mejorar el subsistema, agregando características que los clientes están dispuestos a pagar.

En resumen, este es el arte de lo posible: hacer cambios sin romper las cosas que proporcionan un caso de negocios.

Pero esta no es tu pregunta. Su pregunta es: "Estoy haciendo algo que es enorme y es probable que rompa cosas, y ¿cómo sigo las mejores prácticas?"

Al hacer algo enorme, es cierto que si quieres hacerlo de manera confiable, terminarás gastando más esfuerzo en localizar errores y corregirlos de lo que lo haces escribiendo. Esta es la regla general del desarrollo de software: escribir cosas es fácil, hacer que funcione sin problemas es difícil.

Probablemente tenga un caso de negocios sobre su cabeza, en el que le prometió a algún interesado que este cambio masivo entrará en vigencia. Y está "hecho", por lo que se ve obligado a decir "no, esto no está hecho, solo parece gusta".

Si tiene el poder y el presupuesto, realmente dedique el esfuerzo a generar confianza en que el cambio funciona, o simplemente rechace el cambio. Esto va a ser una cuestión de grado, no amable.

Si no tiene tanta potencia, pero todavía tiene algo, intente insistir en que el nuevo sistema sea ​​comprobable por unidades . Si reescribe algún subsistema, insiste en que el nuevo subsistema esté compuesto de partes pequeñas con un comportamiento bien especificado y pruebas unitarias a su alrededor.

Luego está el peor de los casos. Te profundizas en la deuda. Usted toma prestado contra el futuro del programa al tener más código que es frágil y más errores para poder sacar la función ahora , y malditas las consecuencias. Realizas un control de calidad basado en barrido para encontrar los peores problemas e ignoras el resto. En realidad, esta es a veces la respuesta correcta desde la perspectiva del negocio, ya que ahora es más barato. Endeudarse para generar ganancias es una estrategia comercial válida, especialmente si la liquidación de la deuda por bancarrota (abandono del código) está sobre la mesa.

Un gran problema es que rara vez los incentivos de los propietarios de la compañía están alineados con los tomadores de decisiones y los programadores. Suele haber mucha presión para 'cumplir', y hacerlo generando una deuda técnica casi invisible (para sus superiores) es una gran estrategia a corto y, a veces, a mediano plazo. Incluso si sus superiores / partes interesadas serían mejor atendidos al no crear toda esa deuda.

Yakk
fuente
3
He experimentado la mayor parte de lo anterior tantas veces que es deprimente. La combinación de prácticas de programación de mala calidad, cambios en los objetivos y plazos de gestión poco comprensivos significa que lo que todos sabemos que debería suceder, y lo que realmente sucede, son dos cosas muy diferentes
Ben Hillier, el
44
Esta es una buena respuesta, porque si bien muchos de los otros son técnicos más correctos, esto se compensa en el mundo real y aunque todos queremos vivir en un mundo donde todo está bien probado, bien documentado, no lo hacemos. Código heredado, implementaciones extrañas, malentendidos, partes interesadas irracionales, mal tiempo ... la vida te arrojará cosas malas y tendrás que lidiar con eso.
Allan S. Hansen
25

Resuelva los problemas más grandes que hacen que la revisión del código sea demasiado difícil.

Los que he visto hasta ahora:

  1. Sin conjunto de pruebas unitarias
  2. Fracciones de código complejas que podrían evitarse mediante una estructura de código más sensata y la delegación de tareas de codificación
  3. Una aparente falta de arquitectura rudimentaria
Robert Harvey
fuente
15
  1. Puede devolver la revisión de código y decirle al desarrollador que la divida en conjuntos de cambios más pequeños e incrementales, y que envíe una revisión de código más pequeña.

  2. Todavía puede verificar si hay olores de código, patrones y antipatrones, estándares de formato de código, principios SÓLIDOS, etc., sin tener que pasar necesariamente por cada detalle del código.

  3. Aún puede realizar inspecciones de código táctico para una validación de entrada adecuada, bloqueo / gestión de subprocesos, posibles excepciones no controladas, etc. a un nivel detallado, sin comprender necesariamente la intención general de todo el conjunto de cambios.

  4. Puede proporcionar una evaluación de las áreas de riesgo generales que sabe que pueden verse afectadas por el código, y pedirle al desarrollador que confirme que estas áreas de riesgo han sido sometidas a pruebas unitarias (o solicite que escriba pruebas unitarias automatizadas y que también las envíe para su revisión) )

John Wu
fuente
14

En esta situación, la cantidad de tiempo que llevaría verificar la seguridad de los cambios, la ausencia de regresión, etc. es excesiva.

Las revisiones de código no deben estar dirigidas principalmente a la corrección. Están aquí para mejorar la legibilidad del código, la mantenibilidad y el cumplimiento de los estándares del equipo.

Encontrar errores de corrección durante una revisión de código es un buen subproducto de hacerlos, pero un desarrollador debe asegurarse de que su código funcione perfectamente (incluida la no regresión) antes de enviarlo para su revisión .

La corrección se debe incorporar desde el principio. Si un desarrollador no puede lograrlo, haga que emparejen el programa o elaboren un plan con todo el equipo, pero no lo trate como algo que pueda agregar como una ocurrencia tardía.

guillaume31
fuente
2
De acuerdo, pero: las revisiones de código en realidad tienen un 0º propósito, que es aún más importante que la legibilidad, la facilidad de mantenimiento del código, etc. Son para educar al equipo sobre cuáles son sus estándares. Incluso si no se realizaron ediciones como resultado de la revisión del código, todavía habrían cumplido el 75% de su propósito, porque la revisión educaría al autor del código para evitar cometer ese mismo tipo de errores nuevamente, repetidamente, durante la larga vida futura de este proyecto y el siguiente ...
Jonathan Hartley
1
Ciertamente, también puede desempeñar ese papel, pero he encontrado que la programación de pares es más eficiente que los CR para la incorporación y la educación temprana y media de los nuevos miembros del equipo. Piense en un entrenador que se sienta a su lado durante todo el ejercicio frente a un maestro que solo realiza una evaluación post facto. Tener su trabajo "terminado" corregido por alguien es más frustrante y menos educativo que el trabajo realizado en colaboración con alguien, en mi experiencia.
guillaume31
2
@JonathanHartley: En ese caso, la razón (menos primero) para una revisión de código es hacer que los desarrolladores escriban código que no se avergüencen de mostrar a alguien más en una revisión de código :-)
gnasher729
Estoy totalmente de acuerdo con guillaume31 y gnasher729 arriba.
Jonathan Hartley
11

Si cree que la revisión del código es demasiado difícil, porque cambió el código frágil que es casi imposible de cambiar sin romperlo, entonces tiene un problema. Pero el problema no es con la revisión del código. ¡El problema tampoco está en las pruebas unitarias, porque el código frágil no se puede probar en unidades! Si su código fuera comprobable por unidad, entonces se habría dividido en unidades pequeñas e independientes, que cada una puede probarse, y que funcionan bien juntas, ¡y eso es exactamente lo que no tiene!

Entonces tiene un montón de código basura (también conocido como "deuda técnica"). Lo peor que puede hacer es comenzar a arreglar ese montón de código de basura y no terminar el trabajo porque de esa manera obtendrá un montón de código de basura aún más grande. Entonces, lo primero es lograr que su gerencia compre la solución y termine el trabajo. O no lo haces. En ese caso, simplemente no lo toques.

Cuando lo arregla, extrae una unidad del código, lo convierte en algo que tiene un comportamiento bien definido y bien documentado, escribe pruebas unitarias para esa unidad, revisa el código y reza para que nada se rompa. Y luego haces lo mismo con la siguiente unidad, y así sucesivamente.

La parte difícil llega cuando te encuentras con errores. Sus nidos de código de ratas harán las cosas mal en algunos casos porque las cosas son tan frágiles y complicadas que las cosas saldrán mal. A medida que extraiga unidades, el código restante se volverá más claro. (Tuve un caso en el que después de una refactorización, una función comenzó con "if (condition1 && condition2 && condition3) crash ();" que era exactamente el comportamiento antes de refactorizar, solo que más claro. Luego borré esa línea :-) Verá comportamiento extraño e indeseable claramente, para que pueda solucionarlo. Por otro lado, ahí es donde debe cambiar el comportamiento del código existente, por lo que debe hacerse con cuidado).

gnasher729
fuente
3
La parte difícil es explicarle a la empresa que "Sí, presentaremos algunos errores, pero los solucionaremos y los solucionaremos rápidamente. Un poco de paciencia ahora le dará nuevas funciones y correcciones de errores más rápido en el futuro".
RubberDuck
3

Desafortunadamente, no hay mucho que pueda hacer al respecto en el momento de la revisión del código, aparte de tomar otra taza de café. La solución real para este problema es abordar la deuda técnica que ha acumulado: diseño frágil, falta de pruebas. Con suerte, al menos tienes algún tipo de control de calidad funcional. Si no tienes eso, siempre hay oraciones por algunos huesos de pollo.

JimmyJames
fuente
3

Si no está contento con enviar software defectuoso / que no funciona y solucionarlo más tarde, ¡entonces el esfuerzo de V&V DEBERÍA ser más largo que el esfuerzo de desarrollo!

Si el código existente es frágil, entonces una primera pregunta es "¿debería incluso cambiarlo?" La gerencia debe hacer una llamada para determinar si el costo / riesgo de rediseñar y reimplementar este código es mayor que el costo / riesgo de arreglar la pila tambaleante de basura. Si es algo único, puede ser más fácil simplemente parchearlo. Si es probable que se necesiten más cambios en el futuro, tomar el golpe ahora para evitar más dolor en el futuro puede ser una mejor decisión. Debe plantear esto con su gerencia, porque dar a sus gerentes buena información es parte de su trabajo. Deben tomar esa decisión, porque es una decisión estratégica que está por encima de su nivel de responsabilidad.

Graham
fuente
1

Desde mi experiencia, le recomendaría encarecidamente que cubra su código con una buena cantidad de pruebas, tanto de unidad como de integración, ANTES de que se realicen cambios en el sistema en cuestión. Es importante recordar que hoy en día hay una muy buena cantidad de herramientas para ese propósito, sin importar el lenguaje con el que se esté desarrollando.

Además, existe LA herramienta de todas las herramientas para que pueda crear sus pruebas de integración. Sí, estoy hablando de contenedores y especialmente de Docker y Docker Compose . Nos brinda una forma hermosa de configurar rápidamente un entorno de aplicación complejo, con infraestructura (base de datos, mongodb, servidores de cola, etc.) y aplicaciones.

Las herramientas están disponibles, ¡úsalas! :)

cristianoms
fuente
1

No sé por qué no se ha mencionado aún, pero estas 2 son las piezas más importantes:

  • Divide la lista de cambios en varias listas de cambios más pequeñas, que luego revisa una tras otra. *
  • Si la revisión de una lista de cambios no resulta en una decisión de que la lista de cambios parece ser buena, obviamente rechaza el cambio.

* Ejemplo: reemplaza la biblioteca A con la biblioteca B. Una lista de cambios introduce la biblioteca B, varias listas de cambios diferentes reemplazan el uso de A con B pieza por pieza (por ejemplo, una lista de cambios por módulo), y la última lista de cambios elimina la biblioteca A.

Peter
fuente
1

¿Hacer lo mejor que pueda e intentar solo detectar cualquier falla obvia (tal vez esta es la mayor revisión de código que debería apuntar de todos modos)?

No subestimes el valor potencial de las revisiones de código. Pueden ser buenos para detectar errores:

  • Encuentra errores que serían difíciles de detectar durante las pruebas
  • Encuentre errores que serían difíciles de identificar / corregir durante las pruebas

También son útiles por otros motivos:

  • Ayuda para entrenar a los miembros del equipo.
  • Ayuda para garantizar que el código cumpla con otras métricas de calidad, por ejemplo, ayuda para garantizar que sea comprensible y mantenible y no solo libre de errores

¿Qué hacer en esta situación?

En el caso mejor / ideal, pasar la inspección del código no solo significa "no hay errores obvios": significa "obviamente no hay errores" (aunque, por supuesto, también querrá probarlo).

Si no puede verificar la nueva base de código a través de la inspección de código, necesitará una prueba de "caja negra" más extensa. Es posible que esté acostumbrado a un ciclo de desarrollo en el que ponga el código en producción después de pasar la inspección, pero si no puede "pasar la inspección", entonces no puede "ponerlo en producción" y necesita un ciclo más largo: por ejemplo, pruebas de integración , pruebas del sistema, pruebas alfa, pruebas de aceptación, pruebas beta, etc.

no hay un conjunto completo de pruebas unitarias disponibles o pruebas unitarias no viables para el código fragmentado que ha cambiado

¿Qué pasa con las pruebas de integración, sistema y aceptación?

De todos modos, probablemente debería decirle al gerente de proyecto y al gerente de producto que el código es casi seguro que tiene errores, con un número desconocido de errores; y que "obtendrán lo que inspeccionan" en lugar de simplemente obtener "lo que esperan", es decir, que la calidad del código no es mejor que sus pruebas (porque la calidad del código no ha sido y no puede garantizarse mediante la inspección del código) .

Posiblemente deberían transmitir ese mensaje al cliente o a los usuarios, para que realicen pruebas beta (si están dispuestos a ser los primeros en adoptar), o utilicen la versión anterior hasta que la nueva versión esté fuera de beta (si no lo están).

ChrisW
fuente
0

Mucho código está escrito y fusionado sin una revisión adecuada del código. Puede funcionar. Hay una razón por la cual se llama olor a código, no "código roto" o algo por el estilo. La falta de revisión de código es una señal de advertencia, no un presagio de fatalidad.

La solución a este problema es que no hay una solución única para todos los casos que podamos empaquetar en una respuesta de estilo StackExchange. Es un fuerte consenso de la comunidad de desarrollo de software que la revisión de código es una "mejor práctica" crucial, y en este caso se está omitiendo. Su desarrollo ya no se encuentra en ese estrecho canal de "seguir todas las mejores prácticas". Necesitarás encontrar tu propio camino.

¿Qué es una "mejor práctica" de todos modos? Cuando llega el momento, es un conjunto de prácticas que la gente generalmente piensa que mejora el código. ¿Hacen el código correcto? ¡Diablos no! Internet está plagado de historias de compañías que siguieron las "mejores prácticas" y se atascaron. Quizás un mejor punto de vista de las "mejores prácticas" es que son las soluciones de "disparar y olvidar" del mundo del software. No puedo saber nada acerca de su empresa, su proyecto, su equipo y ser capaz de descartar las "mejores prácticas" como cosas que lo ayudarán. Son el consejo general de "no hacer daño".

Claramente te has desviado de este plan. Afortunadamente, lo reconoces. ¡Buen trabajo! Dicen que el conocimiento es la mitad de la batalla; Si es así, ¡la conciencia es más de la mitad! Ahora se necesita una solución. Según su descripción, está claro que el entorno empresarial en el que se encuentra ha evolucionado hasta un punto en el que el consejo aburrido de "ir a hacer la revisión del código, es la mejor práctica" no va a cortarlo. Para esto, recomiendo una regla clave que uso cuando se trata de las mejores prácticas de software:

Ninguna práctica recomendada de desarrollo de software supera a una necesidad empresarial.

Francamente, están pagando su sueldo, y la supervivencia de la empresa suele ser mucho más importante que la calidad del software. No nos gusta admitirlo, pero un software perfectamente escrito es inútil si está atrapado en el cuerpo de una empresa que muere por sus esfuerzos para mantener ese software perfectamente escrito.

Entonces a donde vas? Sigue el rastro de la fuerza. Usted ha señalado que, por alguna razón no declarada, no es razonable someterse a una revisión de código para alguna tarea. En mi experiencia, esa razón es siempre temporal. Siempre es "no hay suficiente tiempo" o "no hay suficiente dinero para mantener los sueldos fluyendo mientras pasas el tiempo". Esto es un negocio; está bien. Si fuera fácil, todos lo harían. Siga el rastro de la fuerza hacia arriba y encuentre la administración que esté en condiciones de ayudarlo a comprender por qué una revisión de código no es una opción. El lenguaje es difícil, y muy a menudo un decreto se filtrará desde la alta dirección y se distorsionará. La solución a su problema puede estar oculta en esa distorsión.

La respuesta a esto es, necesariamente, un escenario de caso específico. Es similar a tratar de predecir si un lanzamiento de moneda será cara o cruz. Las mejores prácticas dicen voltearlo 100 veces y la expectativa será de aproximadamente 50 caras y 50 colas, pero no tienes tiempo para voltearlo 1 vez. Aquí es donde importan los detalles de su situación. ¿Sabía que una moneda generalmente caerá en la misma orientación que fue lanzada aproximadamente el 51% del tiempo? ¿Te tomaste el tiempo de observar en qué dirección estaba la moneda antes de lanzarla? Podría hacer la diferencia.

Una solución general que puede estar disponible para usted es tratar de encontrar una manera de extraer el proceso de revisión del código y hacer que sea un esfuerzo de muy bajo costo. Gran parte del costo de un proceso de revisión de código es que todos están 100% dedicados a la revisión de código mientras lo está haciendo. Este tiene que ser el caso porque, una vez que se realiza la revisión del código, el código es bendecido. Quizás pueda colocar el código en una rama diferente y hacer la revisión del código en paralelo con el desarrollo en el tronco principal. O tal vez incluso puede configurarlo para que el software haga las pruebas por usted. Tal vez se encuentre en un entorno empresarial donde sus clientes puedan ejecutar el "nuevo" código en paralelo con el anterior y hacer que comparen los resultados. Esto convierte a los clientes en un montón de dispositivos de creación de casos de uso.

Una clave para todos estos "maybes" en ejecución es que debe esforzarse para que su código se divida fácilmente en pedazos. Es posible que pueda "probar" partes del código sin depender de una revisión formal del código usándolas en proyectos menos críticos. Es más fácil hacer esto si los cambios son en partes más pequeñas, incluso si la suma total de ellos es demasiado grande para una revisión por pares.

En general, busque soluciones específicas para su proyecto, su empresa, su equipo. La respuesta de propósito general fue "mejores prácticas". No los está utilizando, por lo que esta vez debería buscar soluciones personalizadas más personalizadas para este problema. Esto es un negocio. Si todo fuera como esperábamos todo el tiempo, las OPI serían mucho más fáciles de asignar valores, ¿no es así?

Si reemplazar una revisión de código es difícil, recuerde que nunca ha habido una sola pieza de código que se haya comprobado que funciona en una revisión de código. * Lo único que hace una revisión de código es darle confianza en el código y la oportunidad de hacer correcciones antes de que se conviertan en un problema. Ambos productos valiosos de una revisión de código pueden adquirirse por otros medios. La revisión de código tiene un valor reconocido por ser particularmente bueno en eso.

* Bueno, casi: el microkernel L4 recibió una revisión de código hace un tiempo por un sistema de prueba automatizado que prueba que su código, si es compilado por un compilador C ++ conforme, hará exactamente lo que dice la documentación.

Cort Ammon
fuente
2
Su respuesta sugiere que el 'sistema de prueba automatizado' revisó el código fuente de L4 automáticamente. En realidad, revisó una prueba escrita por humanos de la corrección de L4. La prueba tardó años en completarse. Sin embargo, hay mucho que aprender de este esfuerzo sobre cómo escribir el código correcto. (Para ser claros, esto no es una prueba de lápiz y papel, sino una prueba legible por máquina que realmente 'importa' todo el código fuente y las razones al respecto. Consulte ssrg.nicta.com.au/publications/nictaabstracts/3783 .pdf )
Artelius el
0

Como @EricLippert señala en su excelente respuesta, este tipo de cambio necesita más atención, no menos . Si se da cuenta de que un cambio en el que está trabajando se convertirá en tal cambio, existen algunas estrategias que podrían ayudarlo:

  • Comprometerse con el control de versiones con frecuencia. La revisión puede progresar compromiso por compromiso y puede ser más comprensible cuando tiene compromisos más pequeños.
  • Asegúrese de comentar los motivos de cada cambio lo más claramente posible.
  • Si es plausible, use la programación de pares para este tipo de cambio. Tener tres pares de ojos sobre el tema en lugar de 2 puede ayudar a evitar problemas que podrían pasarse por alto normalmente, y tener un par mientras estás trabajando puede ayudarte a mejorar cualquier comentario sobre el código que creías obvio pero que resulta ser menos obvio de lo que creías, lo que a su vez ayudará al revisor más tarde. La ayuda para (a) reducir errores durante el desarrollo y (b) mejorar la documentación podría significar que se gastan menos horas de trabajo en esto, a pesar de que hay más personas involucradas.
Jules
fuente
0

Más respuestas abordan cómo llegaste a este punto. Muchos de ellos dan algunas sugerencias para remediar la situación, pero me gustaría arrojar mi respuesta para dar la respuesta breve.

¿Qué hacer cuando las revisiones de código son "demasiado difíciles"?

  1. Regrese a la rama del código de línea principal
  2. Escriba pruebas para la funcionalidad que ha refactorizado (por ejemplo, pruebas funcionales)
  3. Obtenga las pruebas para aprobar
  4. Combina las pruebas en el código que es "difícil de probar"
  5. ¿Aún pasan las pruebas?

si

Ustedes desarrolladores fueron geniales! ¡Gatos para todos!

(o para aquellos que no crecieron viendo " The Simpsons " en la televisión estadounidense: si las pruebas pasan, omita tratar de ver las diferencias y que el desarrollador lo guíe en un recorrido por los cambios)

No

Siga refactorizando y agregando cobertura de prueba hasta que pasen las pruebas.

Greg Burghardt
fuente
77
¿Qué significan los gatos de vuelta ?
JDługosz
@ JDługosz Es la referencia de Simpson ahora.
Rhymoid
No lo entiendo
JDługosz
El instructor de gimnasia, Lugash, tiene la costumbre de confiscar los gatos y perros de sus alumnos, solo devolviéndolos cuando el alumno ha realizado una tarea física. simpsons.wikia.com/wiki/Lugash
Mark McLaren
-1

Al igual que una multiplicación, la revisión del código da un resultado cero cuando se aplica a cero. No aumenta el valor en tal caso, mientras que en la mayoría de los otros casos lo haría.

El código con el que necesita trabajar está demasiado mal diseñado para beneficiarse del proceso de revisión del código durante el desarrollo posterior. Use el proceso de revisión de código para refactorizarlo o volver a desarrollarlo.

También puede ser que el código aún sea soportable, pero la tarea no es buena. Es demasiado amplio y debería haberse hecho en incrementos más pequeños.

h22
fuente
2
@Downvoter, la revisión del código no es un reemplazo para el mal diseño, y los intentos de aplicarlo de todos modos generalmente resultan en cambios que nunca se aprueban, porque el revisor no entiende estos cambios basura en la basura. Perdón por arruinar tu visión.
h22