¿No sería beneficioso escribir pruebas durante la revisión del código?


24

A un colega mío se le ocurrió una idea que me pareció interesante.

¿No sería beneficioso escribir pruebas durante la revisión del código, por la persona que realiza la revisión suponiendo que no hacemos TDD?

Para esta pregunta, suponga que este es un proyecto puramente académico, por lo que no hay vida en juego. Además el equipo es de 4 personas. Todos conocen el idioma y están familiarizados con todas las herramientas / bibliotecas / marcos utilizados y pueden escribir pruebas. Básicamente, las personas que no son ingenieros ninja principales de fullstack sino codificadores decentes.

Pros que encontré:

  1. Alienta una comprensión más profunda del código durante la revisión para escribir pruebas significativas.
  2. Luego, puede agregar una revisión del código de esas pruebas realizadas por el autor del código que se está probando.

Contras que encontré:

  1. El ciclo de retroalimentación entre la escritura de código y las pruebas crece.

EDITAR: Sé que no funcionará bien en aplicaciones web "normales". Lo que tenía en mente era un caso de esquina donde implementaba algoritmos científicos complejos que requieren atención a los detalles. Supongamos algo como implementar mi propia biblioteca de gráficos, PNL, etc. Me pregunto si el código que estamos escribiendo está aislado de las bases de datos y es muy difícil de comprender, pero el nivel adicional de control no sería la otra persona que necesita comprender la fuente. codifique y realice pruebas significativas, haga que todo el proceso sea menos propenso a esos errores menos obvios que no bloquean la aplicación pero que finalmente hacen que sus resultados sean basura.


3
No mencionas si esta serie de pruebas superaría las pruebas que deberían ocurrir durante el desarrollo o en lugar de.
Robbie Dee

3
Sería beneficioso, pero bastante difícil, escribir un test unitario (pruebas de isolotación) si "no hacemos TDD" porque el código no tdd generalmente es difícil de aislar. Escribir pruebas de aceptación y / o pruebas de integración también será difícil y / o frágil si no tiene una capa de abstracción de base de datos (API de repositorio) que le permita definir condiciones previas reproducibles y no frágiles.
k3b

44
@JoulinRouge: TDD ayuda con eso. Como no hay código, no puede adaptar la prueba a su código.
Jörg W Mittag

66
Esto suena como si fuera una revisión de código REALMENTE larga.
David dice que reinstale a Mónica

2
He trabajado en lugares donde una revisión por pares involucró a un compañero programador que revisaba cada línea que había escrito, comparándolos con las pautas de estilo y las mejores prácticas, y escribiendo las pruebas unitarias que no pensó escribir.
candied_orange

Respuestas:


7

¿No sería beneficioso escribir pruebas durante la revisión del código por parte de la persona que realiza la revisión?

He descubierto que un buen momento para escribir exámenes es cuando te das cuenta de que necesitas un examen para una situación.

El cambio de tareas para computadoras es costoso, incluso más para los humanos.

En este momento, generalmente tiene una buena comprensión de los requisitos y dependencias para la prueba. Aproveche la inmersión de su equipo en el problema. Si necesita refinar su nueva prueba en el futuro, excelente, ya tiene el marco / accesorios de prueba en su lugar, y todo lo que necesita hacer es cambiar la parte que necesita mejorar.

Si eso sucede durante la revisión del código, ¿por qué no seguir adelante y hacer eso? Lo he hecho antes. Descubrí que es mejor que no, especialmente si puedes hacerlo rápidamente, e incluso mejor si no lo hubieras hecho de otra manera.

¿Asumiendo que no hacemos TDD?

Incluso si practica TDD, si se da cuenta de que necesita una prueba mientras revisa el código, una que no tiene, ¿por qué no escribir la prueba en ese momento?

Pros

  • Aprovecha su enfoque en el código bajo revisión.
  • A veces, la revisión de código se convierte en tiempo de conversación y chat cuando las personas no están interesadas. Escribir una prueba alienta a todos a pensar más activamente sobre el código que se está revisando.
  • Más miembros junior del equipo tendrán la oportunidad de aprender de la experiencia de redacción de exámenes.
  • Puede identificar el talento en su equipo que no sabía que tenía.

¿Es realmente una estafa que más pruebas puedan conducir a más código? Si se necesitaba la prueba, y el código era necesario para la prueba, y ahora lo tiene, entonces eso es algo bueno .

Advertencias

Tal vez parte del equipo debe centrarse en otras cosas. Si causa una distracción de las prioridades, o su revisión del código excede el cronograma, entonces debe limitar o cortar la redacción real de la prueba. Sin embargo, la revisión del código ciertamente puede identificar las pruebas que deben escribirse, y tal vez al menos puedan ser borradas para que el escritor las complete más tarde.


22

Esta es una idea maravillosa, con una advertencia. No reemplace las pruebas escritas del desarrollador con las pruebas escritas del revisor. Haga que sus revisores busquen casos de esquina y entradas que rompan el código. En otras palabras, haga que traten de escribir nuevas pruebas que el desarrollador original no pensó en escribir.

Escribir pruebas de caracterización es una forma absolutamente maravillosa de comprender un código que no escribió. El hecho de que sus revisores realicen pruebas adicionales en el código les da una mejor comprensión de cómo funciona el código, cómo se puede romper y cómo se puede mejorar. Todo el tiempo, aumentando la cobertura de su código.

Estas son todas las victorias en mi libro.


55
Es casi como si tuvieras experiencia revisando código ...
syb0rg

No tengo idea de lo que estás hablando @ syb0rg ... No puedes probarlo. =;) -
RubberDuck


2
Además, un caso de prueba es la forma menos ambigua de describir una falla descubierta en la revisión :-)
Steve Jessop

1
@ syb0rg Rubber Duck ha ayudado a miles o millones de programadores a arreglar su código . ¿Quién está mejor calificado para revisar el código que uno que haya visto tanto?
jpmc26

18

No creo que la idea carezca por completo de méritos; sin embargo, el principal beneficio de TDD y otros es que los problemas se encuentran temprano . El desarrollador también está mejor ubicado para detectar qué casos de esquina pueden requerir atención específica. Si esto se deja hasta la revisión del código, existe el riesgo de que este conocimiento se pierda.

Escribir pruebas durante la revisión del código sufriría el mismo problema que las pruebas manuales tradicionales: la comprensión de las reglas comerciales puede variar de un desarrollador a otro, al igual que la diligencia.

También existe la antigua discusión sobre si los desarrolladores probarían su código tan bien si supieran que existe una función de prueba más arriba que debería detectar los errores más graves.


Gran respuesta. Pero, ¿qué pasa si no hacemos TDD porque la gente no quiere y no tengo influencia sobre ellos, pero debemos asegurarnos de que el resultado que obtengamos no sea falso positivo porque un error sesgó nuestros resultados? El principal riesgo es que las personas puedan apresurarse a implementar algo sin la comprensión adecuada, escribir pruebas con esa comprensión inadecuada en mente para hacer que las pruebas pasen, pero finalmente produzcan un código incorrecto. ¿Quizás la programación en pareja resolvería el problema? Pero, de nuevo, es fácil obligar a alguien a comprender algo.
Sok Pomaranczowy

Creo que quizás, al igual que alguien más escribiendo las pruebas, estas podrían ejecutarse contra el código de desarrollo mientras el desarrollo está en progreso. Los desarrolladores en cuestión tendrían que estar en la misma página en la que se encuentra el código; de lo contrario, el desarrollador que escriba el código podría realizar constantemente pruebas fallidas de lucha contra incendios en lugar de hacer que realmente funcione.
Robbie Dee

El problema se llama "sesgo conformacional".
ArTs

De hecho, lo diría, distraído del proceso de revisión del código y el código afectaría el proceso de prueba, que no es lo que desea, eliminando la ventaja clave de tener un probador y codificador por separado.
ArTs

1
@RobbieDee Si el receptor de la culpa realmente importa, tienes un entorno de desarrollo poco saludable. Esto es mucho peor que perder algunas pruebas que habrían sido útiles.
jpmc26

5

Estoy de acuerdo con la respuesta de @ RobbieDee pero tengo un poco más que agregar.

Si realmente le gusta esta idea, ¿por qué no hacer que las mismas personas escriban las pruebas antes del código como criterios de aceptación ejecutables para la historia del usuario?

Eso haría lo mismo, mantener los comentarios cortos y hacer que todos tengan una discusión sobre la historia, lo que creo que sería de mayor valor.

Los inconvenientes son el peligro de que se cumplan los criterios de aceptación sin fin :-( y creo que está intentando que la gente en la revisión del código eche un vistazo al código de implementación, pero sugeriría la programación de pares y los pares rotativos como una mejor solución para ese problema.

El OP agregó una edición en la que diseñan más detalles de que esta es una característica difícil o pesada del algoritmo.

En respuesta a eso, agregaría que su instinto de tener más ojos en el problema y la solución es bueno. Tal vez emparejarse con varias personas una a una hasta que todos hayan visto la parte realmente difícil del código de implementación y las pruebas. Cada uno arroja nuevas ideas y agrega más valor.

Hay una idea que a veces se llama programación de la mafia, como emparejamiento pero con más personas. Esto es casi de lo que está hablando, pero ayudan al momento de escribir en lugar de en una revisión formal posterior. Esto no es para todos, y puede requerir un conductor fuerte (líder) para que funcione, o un equipo que se sienta muy cómodo entre sí y con el proceso.

Hacer la programación de la mafia después del hecho, supongo que tendría muchas de las mismas ventajas de que muchos ojos vean el problema y sugieran mejoras, y si así es como su equipo se siente cómodo operando, eso puede ayudar, pero realmente trataría de mantener lo necesario esto ocurre a un mínimo ya que creo que podría ralentizar al equipo.


Quizás los desarrolladores deberían escribir pruebas como mejor les parezca, subirlas al repositorio, pero la persona que realiza la revisión debería escribir sus propias pruebas y nunca mirar las pruebas que escribió el desarrollador. Si ambas suites de pruebas pasan bien, pero si las pruebas de revisión fallan, ¿podría haber un problema?
Sok Pomaranczowy

1
@SokPomaranczowy ha agregado la redundancia en la escritura de pruebas de diferentes personas en el pasado. Creo que si no está haciendo un software vital, entonces ese es un esfuerzo desperdiciado y, en su lugar, debe concentrarse en dónde es mejor pasar su tiempo (nunca escribirá TODAS las pruebas) y con una buena comunicación en el equipo, creo que Es un enfoque mucho mejor.
Encaitar

@Encaitar Estoy de acuerdo, esto suena como una gran pérdida de tiempo que probablemente no mejorará mucho las cosas. RoI y todo eso ...
sara

3

Como usted dice, si está ejecutando un equipo TDD, entonces esto es discutible ya que el código ya debería ser probado.

En general, no creo que esta sea una gran idea, pero depende de su enfoque actual y de lo que funcione para usted. Básicamente, el problema que veo es que pierdes la ventaja del "ciclo de retroalimentación corta" de las pruebas. Recibir notificaciones instantáneas en el momento en que rompes algo, incluso mientras escribes un nuevo código, es donde realmente brillan las pruebas. Si pospone la prueba hasta la revisión del código, básicamente está diciendo "bueno PODRÍAMOS haber solucionado este problema antes en menos tiempo y con menos personas involucradas, pero al menos todos aprendimos algo (tal vez)". Prefiero simplemente asegurarme de que las personas envíen el código probado para su revisión, y luego juzgar la corrección y facilidad de mantenimiento de las pruebas. Después de todo, la revisión de código es para revisar, no para escribir código.

Por otro lado, le recomiendo que FIDDLE con las pruebas / código durante la revisión. Intenta romper algo. Comente una condición if. reemplace un booleano con un literal verdadero / falso. Vea si las pruebas están fallando.

Pero sí, en general, le recomiendo que escriba sus pruebas junto con su código y luego lo revise todo de una vez.


2

Depende de lo que esté haciendo en la revisión de código. Creo que hay dos razones principales para escribir pruebas en esa etapa:

  • primero, si también refactoriza durante la revisión del código, y observa que no hay suficientes pruebas unitarias para cubrir el tipo de refactorización que desea aplicar, agregue tales pruebas

  • segundo, si el código te parece que podría tener un error y quieres probarlo (o refutarlo), escribe una prueba para ello

Ambos casos expresan la necesidad de pruebas que no están disponibles en este momento, pero deberían estarlo. Por supuesto, puede depender de la cultura de su equipo si este tipo de pruebas deben ser escritas por el revisor o por el autor original, pero alguien debe escribir las pruebas.

En realidad, no creo que este sea un "caso de esquina" solo adecuado para "algoritmos científicos complejos"; todo lo contrario, esto es adecuado para cualquier tipo de software del que se espera un cierto grado de calidad.


2

No, no lo hagas. Les harás pensar que TDD es horrible.

Creo que @ k3b tiene razón en los comentarios sobre la pregunta. El código escrito a través de un proceso de estilo TDD tiende a verse e interactuar de manera muy diferente al código escrito sin pruebas. Agregar pruebas (buenas) al código no probado generalmente requiere mucha refactorización del código para aclarar su intención y partes móviles.

Al agregar las pruebas después de escribir el código, se pierden los aspectos arquitectónicos de los beneficios de TDD (que en mi opinión son uno de los principales beneficios). No solo eso, le está pidiendo a otra persona, que no está tan familiarizada con el código, que tome el éxito de agregar pruebas que ya son difíciles de agregar.

O la persona que agrega las pruebas tendrá que refactorizar significativamente el código, o tendrá que trabajar muy duro para probar el código no comprobable. De cualquier manera, no van a disfrutar la experiencia. A pesar de que esto podría no ser un TDD clásico, no lo verán de esa manera, y podría posponerlos de una vez por todas.

(Si ya está siguiendo un proceso de TDD, escribir pruebas adicionales durante la revisión del código sería menos dañino, aunque en mi experiencia, si las pruebas ya están bien escritas, es igual de fácil explicar la prueba adicional a la persona que envía el código para revisión y pídales que los escriban).


1

Las pruebas unitarias durante la revisión del código son un mal sustituto de las pruebas unitarias durante el desarrollo.

Lo que estás sugiriendo tiene mucho sentido, intuitivamente. ¿Para qué es la revisión? Para comprobar que el código es bueno. ¿Para qué son las pruebas? Para comprobar que el código es bueno. Entonces, ¿por qué no combinar los dos?

Este es el por qué.

Poner el código a prueba es un trabajo duro. Escribir código que solo funciona en la única cosa que debe hacer es una cosa; escribir código que pueda ser probado de manera efectiva y eficiente es otro. El solo hecho de que el código ahora se ejecuta bajo dos escenarios: "trabajo real" y "prueba", exige una flexibilidad mucho mayor, exige que ese código sea capaz de mantenerse por sí solo de manera significativa.

Escribir su código para que sea comprobable es un trabajo y habilidad adicionales. Refactorizar el código de otra persona para la comprobabilidad, cuando no se escribió teniendo en cuenta la comprobabilidad, puede ser una tarea importante.

Estás duplicando el esfuerzo entre el desarrollador y el revisor. Presumiblemente, su desarrollador no está entregando su código para su revisión sin al menos un cierto nivel de confianza de que está funcionando. Él ya necesita probar el código. Ahora, hay diferentes niveles y alcances de pruebas. QA prueba el código después del desarrollador y el revisor. Pero sea cual sea el alcance que considere apropiado para el desarrollador y el revisor, no tiene sentido que el desarrollador descubra cómo probar el código a ese nivel una vez , sino que haga que sus pruebas sean descartables y difíciles de reproducir, y luego lleve al revisor a desarrollar prueba nuevamente, esta vez las que son automatizadas y reproducibles. Solo hace que ambos inviertan tiempo en escribir las mismas pruebas, una vez mal, una vez bien.

Estás convirtiendo la revisión en un paso mucho más largo y laborioso. Si las pruebas son una parte importante del proceso de revisión, ¿qué sucede cuando algunas pruebas fallan ? ¿El revisor es responsable de ejecutar todas las pruebas, por lo que también necesita depurar el código? ¿O va a ser sometido a ping de ida y vuelta, una prueba de escritura y la otra haciendo que pasen?

A veces puedes escribir un montón de pruebas que son ortogonales entre sí, por lo que no necesitas hacer ping-pong. El revisor escribe una docena de pruebas, la mitad de ellas fallan, el desarrollador corrige los errores y todas las pruebas siguen siendo válidas y pasan ahora. Pero ... muchas veces, tienes errores de bloqueo, o errores que requieren rediseño y cambios de API, o cualquier otra cosa. Si usted está asumiendo la responsabilidad de pasar las pruebas entre el revisor y el desarrollador, entonces no está realmente en la etapa de revisión. Aún te estás desarrollando.

La necesidad de escribir exámenes no incentiva una revisión más exhaustiva. Básicamente significa que cuanto más profundo vayas, más pruebas tienes que escribir, y probablemente serán pruebas difíciles que deben profundizar en el sistema.

Compárese con el desarrollador que escribe las pruebas, donde está su incentivo: si no escribo pruebas importantes, el revisor lo señalará en la revisión.

Incluso el revisor tendrá una mejor comprensión del sistema si necesita revisar minuciosamente el código , y si necesita decidir por sí misma cuándo puede dejar de escribir una prueba de excavación profunda y simplemente aceptar la revisión del código.

Si el desarrollador no escribe pruebas unitarias, el revisor tampoco lo hará. Existen muchos obstáculos para adoptar las pruebas como una práctica común. Tal vez estás bajo demasiada presión, y tu base de código es difícil de poner a prueba. Tal vez no tenga tanta experiencia en las pruebas y sienta que no puede permitirse la curva de aprendizaje. Tal vez tienes un asesino con hacha que envía notas amenazantes a las personas que escriben pruebas. ¡No lo sé!

Pero sea cual sea la causa, es seguro apostar que se aplica por igual al revisor y al desarrollador. Si el equipo está estresado, el revisor no tiene más tiempo que el desarrollador (si lo hace, redistribuya el trabajo para que la gente no esté tan estresada ). Si nadie sabe cómo escribir bien las pruebas unitarias, el revisor probablemente tampoco (si lo sabe, debería sentarse y enseñar a sus compañeros de equipo ).

Esta sugerencia suena como tratar de pasar el dinero de un colega a otro. Y simplemente no veo ninguna manera de que eso funcione bien, en primer lugar porque es realmente difícil (y poco saludable) crear una situación en la que una persona es la única que puede hacer pruebas, y otra persona no puede hacer cualquier prueba en absoluto.


Lo que funciona es que la revisión cubra las pruebas también. Si el desarrollador ya ha escrito diez pruebas, es mucho más probable que el revisor pueda ayudar a sugerir otras diez, que si el desarrollador no hubiera escrito ninguna.

Y, si probar casos clave es una tarea importante, podría tener sentido distribuirlo más ampliamente en todo el equipo. ** Una vez que el código es comprobable en primer lugar, escribir más pruebas se vuelve mucho más fácil. ** **

La revisión es un buen momento para detectar casos de esquina. Y, si el revisor puede entrar y escribir una prueba para los casos de esquina que encuentra, entonces, ¡ojalá! ¡Mucho mejor! Pero en general, suponiendo que el revisor puede escribir pruebas donde el desarrollador no parece una idea muy mala.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.