¿Cómo puedo evitar causar errores en el software cuando soluciono errores no relacionados? [duplicar]

48

Soy un pasante de software y me asignan errores para corregir, así como funciones para agregar al software. Cuando agrego características, todo funciona bien. Mi problema es más con la corrección de errores. Estoy trabajando en una base de código extremadamente grande (que abarca millones de líneas) con una documentación deficiente (no hay comentarios, toneladas de números mágicos, acoplamiento apretado entre diferentes clases, etc.). La única documentación proporcionada es un documento de Word de 8 o más páginas. Pero sigo sintiendo que puedo hacer un mejor trabajo con la corrección de errores.

Daré un ejemplo de una situación que me he encontrado, y creo que podría haberlo hecho mejor en:

  • Me asignaron un error para corregir con respecto a los cálculos de extensión para un tipo específico de objeto (gráficos de computadora)
  • Encontré el problema con el error y por qué fue causado. Debido a que el programa completó una estructura de datos (matriz contigua) con memoria que representa un punto cartesiano 3D que aparentemente no debería tener (por lo tanto, este punto se usaría en los cálculos de extensión).
  • El error fue causado por esto. SIN EMBARGO, otra pieza de código (en una clase diferente) usó la aritmética de punteros para obtener este punto y usarlo para otra característica, para hacer que el mouse se ajuste cerca de este punto cuando se habilitó cierta característica en el software. Sin embargo, desde que eliminé el punto, arreglé el error que me asignaron y causé otro error en el software.

¿Qué puedo hacer para que no ocurran cosas como esta? ¿Cómo puedo mejorar? ¿Hay algún proceso que me esté perdiendo?

    
pregunta Jason 14.09.2017 - 05:23

7 respuestas

70

No puede ser el único responsable de este tipo de defectos. Eres humano y es imposible pensar en grandes sistemas en su conjunto.

Para ayudar a prevenir los "errores de regresión": los errores que se crean involuntariamente al modificar el sistema, puede hacer lo siguiente:

  • Desarrolle un conjunto completo de pruebas de regresión automatizadas. Esperemos que su sistema tenga un gran conjunto de pruebas. Cada vez que se descubre un error en su sistema, debe escribir una prueba automatizada que reproduzca el error. Entonces arregla el error. Si alguna vez el sistema retrocede, su "prueba de regresión" se interrumpirá y notificará al desarrollador.
  • inspeccionar el código. Siempre que corrija un error, es una buena idea inspeccionar los usos de la función que ha cambiado para intentar identificar cualquier cambio importante que haya introducido
  • Escribe más pruebas. Si al inspeccionar el código, usted identifica un código que no está cubierto por ninguna prueba automatizada, esta es una buena oportunidad para agregar algunos.
  • Familiarícese con el sistema y trabaje con el software durante mucho tiempo. La práctica hace la perfección. Nadie espera que un desarrollador no introduzca errores en un sistema completamente nuevo o cuando sea un interno. Todos lo hemos hecho.
respondido por el Samuel 14.09.2017 - 05:42
10

No puedes eliminar esto en ningún sentido completo. Aquí hay algunos pasos para disminuir el impacto y disminuir la probabilidad:

  1. Agregue una prueba unitaria y una prueba de regresión para la funcionalidad o error que está cambiando o corrigiendo. Si no tiene ningún marco de prueba o arnés configurado para su proyecto, configúrelo para que sea parte de su proceso. Esto mejorará las cosas con el tiempo.
  2. Mejore el diseño de su código para que el código esté acoplado de manera más flexible. Eso significa seguir el SRP, incluso significa sacrificar algo de DRY. En particular, en los sistemas OOP, su código y sus datos deben estar en la misma clase y los datos siempre deben ser privados. Si esto no tiene sentido, hay una discrepancia de impedancia entre el dominio del problema y el diseño. No debería ser posible que un cambio en la estructura de datos en una clase afecte el comportamiento de otra clase.
  3. Hable con sus compañeros de trabajo acerca de la solución propuesta. Esto podría tomar la forma de revisiones de código, pero a veces eso no captura las regresiones. Las revisiones de código no suelen ser para atrapar errores. Como corolario, asegúrese de que el resto del equipo esté al tanto de los cambios que está realizando y deles tiempo para que le den su opinión sobre qué otras partes del sistema pueden depender del código. Haz esto incluso si eres la persona mayor en el equipo.

Espero que esto ayude.

    
respondido por el RibaldEddie 14.09.2017 - 05:55
8

Hay muchas buenas sugerencias en otras respuestas. Me gustaría agregarles: su organización probablemente tenga un problema en el nivel de administración.

  • La administración puede estar priorizando el trabajo de nuevas características en lugar de abordar la deuda. El error que mencionó es una evidencia de que las malas prácticas del pasado hacen que sea más costoso desarrollar software libre de errores en la actualidad. Recopile puntos de datos como estos para informar a la gerencia que hay un problema continuo causado por una deuda no resuelta, y que sería conveniente programar un "hito de calidad" en el que no se agreguen nuevas características, pero la deuda existente se reduzca.

  • Es probable que la administración ignore el alcance del problema. Las herramientas de análisis estático que encuentran errores reales son caras, pero son mucho más baratas que fallar en el mercado porque usted envió software que pierde datos de usuario. Un buen analizador estático le dirá que tiene decenas de miles de errores no resueltos, dónde están y cómo solucionarlos. Esto le permite controlar el tamaño del problema y qué tan rápido lo está mitigando.

respondido por el Eric Lippert 14.09.2017 - 13:45
5
  

En el tema de reformar cosas, a diferencia de deformarlas, hay un principio claro y simple; un principio que probablemente se llamará una paradoja. Existe en tal caso una determinada institución o ley; Digamos, en aras de la simplicidad, una valla o puerta erigida a través de una carretera. El tipo de reformador más moderno se alegra y dice: "No veo el uso de esto; dejémoslo claro ". A lo que el tipo de reformador más inteligente le responderá:" Si no ves su uso, ciertamente no te dejaré que lo borres. Vete y piensa. Entonces, cuando puedas volver y decirme que ves su uso, puedo permitirte que lo destruyas ".

- G.K. Pechera

Además de todas las otras ideas aquí planteadas, otra cosa valiosa que hacer es descubrir cómo y por qué se introdujo un error. Suponiendo que su equipo utilice Git o un sistema de control de fuente similar, herramientas como git blame o el botón Blame de GitHub pueden ayudar con esto. Una vez que haya identificado la línea o líneas de código incorrectas que causaron el error, use las herramientas de control de origen para averiguar cuándo se agregó, quién lo hizo y como parte de un cambio más amplio.

Cada vez que corrijo un error, trato de escribir en el rastreador de errores de la organización una narrativa de cómo creo que el error llegó a existir. A veces es una historia tonta y un poco vergonzosa como "Parece que Bob comentó la línea 96 con fines de prueba, la cometió accidentalmente en cometer 5ab314c, y se fusionó porque nos apresuramos a desplegar el Frobnicator y no revisamos de forma adecuada esa semana. " Aún así, aprendiendo que es bueno , en el punto en que estás resolviendo el error, porque te asegura que probablemente no haya una buena razón para que el código roto sé como es y te permite arreglarlo con más confianza. Pero a veces se adentra en el git blame y se encuentra que la línea de código "obviamente rota" que estaba a punto de cambiar se introdujo en una confirmación que pretende corregir algún otro error que no había ha pensado, y de repente te das cuenta de que tu "solución" va a hacer algún daño y que necesitas hacer algo más inteligente.

Por supuesto, como señalan muchas otras respuestas aquí, sería bueno si el desarrollador anterior hubiera dejado atrás una prueba que fallaría si reintroducieras ingenuamente un error antiguo, una especie de advertencia automática de que la cerca que estás a punto de derribar tiene un propósito que no puedes ver. Pero no puedes controlar cuántas pruebas escribieron los desarrolladores anteriores de tu base de código, porque eso es el pasado; profundizar en el historial del código es una de las pocas técnicas disponibles para usted en el momento de corregir un error existente para reducir el riesgo de romper cosas.

    
respondido por el Mark Amery 14.09.2017 - 15:26
1
  

"otra pieza de código (en una clase diferente) usó aritmética de punteros para obtener este punto y usarlo para otra función, para hacer que el mouse se ajuste cerca de este punto cuando se habilitó cierta función en el software."

Sí, te han entregado un código base de alto mantenimiento. Parece que en este caso, en lugar de un acoplamiento regular entre objetos con interfaces obvias, hubo algo de "magia", que por supuesto dejó de funcionar tan pronto como se cambió.

No hay truco de magia para esto. Muchas técnicas de desarrollo de software se centran en la gestión de la complejidad para poder detectar cuál será el impacto de un cambio, pero no se han seguido aquí . Esto es culpa de los desarrolladores anteriores y las personas mayores que supervisan el proyecto.

    
respondido por el pjc50 14.09.2017 - 13:21
1

También trabajo en una aplicación legada frágil. Mi objetivo número uno para cualquier cambio es "no romper nada de lo que funcionaba anteriormente". (El objetivo número dos es que el usuario debe poder terminar su trabajo, incluso si se pone un poco torpe o si tiene que invocar alguna solución alternativa, no puede quedar totalmente atascado en ningún momento).

  1. Hay un libro, Trabajando eficazmente con el código heredado por Michael Feathers. Es bastante útil, pero le advertiré que es 100% acerca de agregar pruebas automatizadas. Técnicamente siempre es posible (y él explica cómo hacerlo para muchas situaciones difíciles) pero no siempre es viable desde la perspectiva del negocio. El libro también es útil porque tiene pequeñas barras laterales divertidas sobre lo que pueden hacer las cosas mal.
  2. Inspección manual tediosa de todo lo que toca el punto de cambio. Si cambió dos funciones, foo y bar, realice una búsqueda de texto completo en toda la base de código (lo tiene TODO comprobado, ¿no?) Para las palabras foo y barra. (Tenga en cuenta que querrá convertirse en un usuario avanzado de alguna herramienta de búsqueda como grep). Es importante no intentar simplificar esta búsqueda ... no solo busque en archivos Java, ya que su función puede llamarse mediante la reflexión. a partir de algo iniciado en un JavaScript de front-end ... solo un ejemplo. Mantenga el seguimiento hasta que haya probado por completo todo lo que requiere su cambio.
  3. Invierta su técnica de búsqueda e intente encontrar puntos en su aplicación haciendo lo mismo sin llamar su punto de cambio. Busque el código copiado y pegado o la misma cosa hecha de dos maneras y asegúrese de haber cambiado todos los puntos que necesitaban ser cambiados. (Luego repite el paso anterior).

Suena horrible, pero estas aplicaciones heredadas, difíciles de mantener, generalmente solo están disponibles y se están actualizando porque están haciendo algo importante y alguien realmente las necesita para trabajar. Trate de obtener algo de satisfacción con esto.

    
respondido por el user3067860 15.09.2017 - 00:30
0

Puede refactorizar el código para ocultar el acceso directo a ese miembro específico y agregar un descriptor de acceso. Esto romperá cualquier código que dependa del acceso directo al miembro, por lo que sabrá cada lugar que lo usa.

Como bonificación, reubique al miembro y complete su lugar anterior con basura, esto romperá el código que accede a él mediante la aritmética de punteros.

Como desarrollador, quieres que tu código se rompa temprano, quiebra a menudo. "Funciona 99.99% o el tiempo" es mucho peor para corregir errores que "no funciona en absoluto".    (por supuesto, para el código de producción, no desea el "descanso temprano, descanso a menudo")

    
respondido por el Calin Ceteras 14.09.2017 - 09:44

Lea otras preguntas en las etiquetas