¿Cómo motivar a los compañeros de trabajo para escribir pruebas unitarias? [cerrado]

92

Estamos trabajando en un producto grande que ha estado en producción durante aproximadamente 5 años. La base de código está ... erm ... funcionando. No muy bien, pero está funcionando. Las nuevas características se lanzan a producción y se prueban con un pequeño control de calidad. Los errores son corregidos, etc. Pero nadie, excepto yo, está escribiendo pruebas unitarias. Nadie usa el poder de "rastrear" errores al escribir pruebas unitarias para garantizar que este error especial (caso de prueba) nunca vuelva a ocurrir.

He hablado con la gerencia. He hablado con desarrolladores. He hablado con todos en toda la empresa. Todos dicen: "Sí, debemos escribir más pruebas unitarias". Eso fue hace un año. Desde entonces he forzado introducción de pre-commit revisión de código ( Gerrit ) y la integración continua ( Jenkins ).

Realicé algunas reuniones sobre pruebas unitarias y también mostré los beneficios de escribir pruebas unitarias. Pero nadie parece estar interesado.

P1: ¿Cómo puedo motivar a mis compañeros de trabajo para que escriban pruebas unitarias?

P2: ¿Cómo me mantengo motivado para seguir los estándares de calidad de mi código personal? (¡A veces es realmente frustrante!)

PD: Algunos hechos frustrantes (alcanzados en 1 año):

  • Total de pruebas unitarias: 1693
  • Total de "pruebas unitarias de ejemplo": alrededor de 50
  • Hecho por mí: 1521

Editar: ¿Estoy esperando demasiado? Es mi primer lugar de trabajo y estoy tratando de hacerlo lo mejor posible.

Edición 2: Basado en todas las respuestas, hice una pequeña lista de verificación para mí. He hablado con dos desarrolladores en privado y tuvimos una charla buena y honesta.

Uno de ellos me dijo, como dijo Telastyn , que está realmente incómodo con las pruebas unitarias. Dijo que le gustaría ser "más profesional" pero que necesita un arranque rápido. También dijo que nuestra reunión de prueba unitaria con todos los desarrolladores (alrededor del 11 de septiembre) fue buena, pero fue demasiado concurrida. Meh Algunas críticas para mí, pero aprenderé de eso. (¡vea las respuestas a continuación sobre las reuniones de tdd kata!)

El otro dijo que no está interesado en escribir pruebas unitarias. Él piensa que su trabajo es lo suficientemente bueno para su salario. No quiere poner más esfuerzo. Me quedé sin palabras. Típico 9-5 "trabajador".

La semana que viene voy a hablar con los otros desarrolladores.

Gracias por sus excelentes respuestas (hasta ahora) y su apoyo. ¡Realmente lo aprecio! He aprendido mucho, muchas gracias!

lurkerbelow
fuente
¿Las otras 172 pruebas unitarias fueron realizadas por usted en años anteriores o alguien más está haciendo pruebas unitarias que está trivializando su contribución?
JB King
16
Esas otras 172 pruebas unitarias fueron realizadas por un desarrollador que dejó la compañía. triste :(
lurkerbelow
66
Por favor sigue hablando de números. Cuántos errores descubrieron en el último año, cuántos de ellos fueron descubiertos y cuántos fueron prevenidos por las Pruebas de Unidad. Cuánto tiempo escriben las pruebas (1521 en un año por una persona) frente a "Hacer un trabajo real" (en términos que probablemente piensan sus compañeros de trabajo). ¿Perciben UT como beneficioso o una pérdida de tiempo? es decir, muéstrame el dinero.
mattnz
1
Por curiosidad, ¿tienen sus compañeros de trabajo una estrategia de depuración alternativa? TDD es útil para probar que algo funciona como se esperaba, pero no tanto para problemas desconocidos. Pueden sentirse cómodos simplemente enganchando un depurador.
Spencer Rathbun
3
Enganchar un depurador con fines de prueba es correcto, pero no garantiza que el código funcione en unos pocos días / semanas / meses y ese es el verdadero problema.
lurkerbelow

Respuestas:

48

Me di cuenta de que hablar de TDD apenas funciona. A la gente le gusta ver resultados crudos . Decir que "escribir pruebas reducirá el tiempo de desarrollo" probablemente sea cierto, pero podría no ser suficiente para convencer a nadie.

Estaba en una posición similar (bueno, no tan mala como la tuya), y se resolvió cuando la gente comenzó a trabajar en mi código (nota: mi código fue probado por la unidad, otros no tanto). Cuando algo dejó de funcionar, el seguimiento natural después de una investigación local fue preguntarme cuál podría ser la razón . Luego nos sentamos, realizamos pruebas unitarias y vimos lo que sucedió. Si las pruebas pasaban, la mayoría de las veces los problemas estaban en el nuevo código no probado. Si no, las pruebas generalmente pudieron detectar el problema (o al menos señalarnos en la dirección correcta). Arreglamos el error, las pruebas se hicieron nuevamente, todos estaban felices.

En pocas palabras, ocurrieron algunas situaciones como esta y 2 desarrolladores más se convirtieron en entusiastas de TDD / testing (todavía quedan algunos más, pero parece prometedor).

En cuanto a consejos, puedes probar con TDD kata; tarea simple de implementar usando un primer enfoque de prueba en lugar de ninguna prueba . Dependiendo de lo compleja que sea la tarea, el enfoque que no sea de prueba generalmente debería ser más lento, especialmente con los cambios necesarios incrementales:

Editar : el comentario de OP me hizo darme cuenta de que hay argumentos aún más fuertes a su disposición: la regresión, también conocida como errores que regresan . Ese tipo de situaciones son ejemplos perfectos que demuestran cuán beneficiosas pueden ser las pruebas unitarias. A la gente le gustan los números, como dije, decir que "la prueba unitaria es buena" podría no ser convincente, pero organizar los datos como a continuación seguramente podría ser:

  • tiempo dedicado a implementar la función (no se escribieron pruebas; supongo que esto sucedió a menudo, por lo que debería ser relativamente fácil encontrar ese ejemplo)
  • tiempo estimado para implementar la función con TDD (o incluso pruebas después del enfoque; no importa; lo importante es la presencia de pruebas unitarias)
  • tiempo dedicado a resolver el error en código no probado vs probado

Una cosa para advertirle (esta migración es obvia pero vale la pena señalar): sesgo de resultado : asegúrese de no seleccionar un ejemplo en el que la única forma de detectar el error con la prueba sea escribir una prueba para ese error. Por lo general, nadie sabe que se producirá un error por adelantado, pero es tentador decir "hombre, este error sería trivial si tuviéramos una prueba para X" : es fácil encontrar una táctica ganadora para una guerra después de que haya terminado.

El resultado de esos ejemplos debería ser una pregunta simple: si pudiera pasar x horas desarrollando la función Y, ¿por qué insistiría en hacerlo en 2x ?

jimmy_keen
fuente
Gracias por tu contribución. Creo que voy a programar una reunión de TDD con katas ... Dos desarrolladores por reunión para poder ayudar. Sí, el software "funciona". Pero muchos errores son "recurrentes". Si alguien arregla algo en el módulo A, tal vez el submódulo A1 ya no funcione en algunos casos. Esos errores (en su mayoría) no se encuentran durante el control de calidad. Eso es una pérdida de tiempo. Escritura de pruebas unitarias: (tal vez) 1h. Obtención de un informe de error del cliente, análisis, planificación, reparación, revisión de código, construcción, entrega de revisiones, etc., aproximadamente ... 6-8h.
lurkerbelow
La imagen vale más que 1000 palabras y todo. Mostrar que ahorra tiempo es más convincente que decir Esto debería ahorrar tiempo .
R0MANARMY
44
@lurkerbelow: el argumento de los errores de retorno (o regresión si lo desea) es muy fuerte. Piense en arreglar el problema o error existente en el que ha dedicado demasiado tiempo en esos ejemplos, y muestre cómo podría haber ayudado tener pruebas escritas.
km
10
En mi experiencia, escribir pruebas no reduce el tiempo de desarrollo, al menos no por adelantado; lo aumenta Sin embargo, produce software más confiable, mejor diseñado y más fácil de mantener.
Robert Harvey
@RobertHarvey: tienes razón en eso, "desarrollo" es una mala elección de redacción de mi lado. No se me ocurrió nada mejor para describir el proceso de diseño, implementación, lanzamiento y mantenimiento de una pieza de software. UT a largo plazo, acortar / simplificar este proceso y eso es lo que tenía en mente.
km
28

Primero debes saber por qué no escriben exámenes.

Los horarios de desarrollo ajustados son a menudo la razón, pero usted dice que no tiene eso.

La siguiente razón es que con una gran base de código no probado existente, escribir pruebas probablemente parece abrumador, un trabajo interminable (como lavar y casi tan emocionante). Entonces, la naturaleza humana es pensar que es demasiado para enfrentar, así que lo omitiré.

Otra razón podría ser que, si bien consideran que los exámenes son una buena idea, no tienen confianza en cómo comenzar a escribirlos, especialmente si nunca han trabajado en un lugar que los haya escrito.

Otra posibilidad importante es porque realmente no ven ningún valor para más trabajo a pesar de que están dando un toque de gracia a la idea.

Entonces, ¿cómo manejas las diferentes razones?

La razón uno es simple, muéstreles un ejemplo de cómo ahorra tiempo de desarrollo.

Razón dos: muéstreles cuántas pruebas ha escrito en un año y qué porcentaje de la base de código cubre. Haga los cálculos para mostrar cuántas pruebas más podrían tener en este momento el próximo año si hacen esto. Una vez que ven que los pequeños avances diarios se suman realmente, la idea no es tan abrumadora. Si puede extraer los datos del sistema, muéstreles cuántos errores fueron errores repetidos en las partes no probadas del código y cuántos errores repetidos aparecen en el código con las pruebas unitarias.

La razón 3 es entrenar, no solo mostrar. Haz que escriban exámenes en una clase de entrenamiento.

Razón 4, este es el quid de la cuestión. Primero, elija un punto de dolor, uno de esos errores que ha regresado varias veces. Cuando eso llegue, este es el momento de sugerirle a la gerencia que si tuvieran pruebas unitarias de este artículo, no volvería como un centavo malo.

Otra forma de abordar la razón 4 es hacer que la administración lo haga parte del proceso y el código no aprueba la revisión del código a menos que las pruebas también aprueben la revisión del código. Es mejor abordarlos haciendo de esto una política justo después de uno de esos puntos críticos o preferiblemente justo después de haber tenido varios en cuestión de días.

A todos nos gusta pensar que, como desarrolladores, nos autogestionamos (LOL), pero a los ambiciosos les importará lo que la gerencia les enfatice que deberían importarles y los profesionales que realmente se autogestionan ya están escribiendo las pruebas. Si a ellos no les importa ser profesionales y hacer mejores prácticas porque mejoran el producto o les importa impresionar a los gerentes para que sean promovidos (o no despedidos), entonces puede considerar si este es el lugar adecuado para usted. Si no puede lograr que la gerencia se preocupe por las mejores prácticas, entonces estará librando una batalla cuesta arriba todo el tiempo y nuevamente, podría evaluar si esta es la cultura corporativa adecuada para usted. Si bien cada lugar de trabajo tiene sus problemas (y huir no siempre es la respuesta), este lugar no parece ajustarse a su nivel de profesionalismo.

HLGEM
fuente
9

Me gustaría empezar por demostrar los beneficios de TDD. Trate de mostrar los beneficios de las pruebas unitarias.

Como seres humanos normales, los desarrolladores están motivados por los beneficios. No quieren hacer cosas que solo crean más trabajo. Las pruebas unitarias significan menos trabajo . Significa salir más con amigos. Significa divertirse más porque no tiene que pasar todas las noches codificando hasta las 11 p.m. Significa ir de vacaciones más con tranquilidad.

Uno de los mayores beneficios de TDD es que puede refactorizar su programa para un mejor diseño o simplemente cambiar el nombre de algo ... y siempre que ese diseño no rompa las pruebas, puede tener el 100% de confianza de que su cambio No rompió nada.

Otro gran caso para TDD es crear pruebas unitarias para código heredado . Esto representaría una de las mejores formas de comenzar a refactorizar el mal. A la larga, esto servirá para mejorar su conocimiento de la base del código, comprender sus fortalezas y fallas, detectar la lógica comercial codificada en el código y darle un buen comienzo para mejorar la calidad en el futuro.

Buenas referencias para lecturas adicionales:

ElYusubov
fuente
3
@lurkerbelow, ok, y ahora su próxima tarea es monitorear esos sloc en busca de errores: vigile su rastreador de errores y los cambios de código que surjan. Si no hay errores, entonces su colega tiene un punto. Si hay cargas, entonces tienes un punto. De cualquier manera, tendrá alguna evidencia empírica.
gbjbaanb
3
El hecho de que pueda probar que sus cambios no rompieron algo más es un GRAN poder en mi opinión. La respuesta inmediata del software de trabajo también es útil. Desafortunadamente, algunas personas nunca querrán intentar el aprendizaje de inicio. Irónicamente, ese inicio limitado para la gratificación inmediata es demasiado en nuestra cultura de gratificación inmediata ...
Jennifer S
7

http://blog.jtimothyking.com/2006/07/11/twelve-benefits-of-writing-unit-tests-first

Creo que marqué ese enlace de un artículo de Jeff Atwood hace algún tiempo [edit: sí, aquí está] . Viejo pero relevante. Debido a estos beneficios y otros que sin duda se detallarán en otras respuestas, ¡sus programadores deberían poder motivarse ! Les permitirá trabajar de manera más eficiente y así facilitar su trabajo. ¿Quién no quiere eso?

En lo que respecta a su segunda pregunta: su sentido de propiedad y orgullo en los estándares de calidad de su código deben mantenerlo con ellos . Piense en lo que quiere lograr al tener tales estándares y quién se beneficia de ellos. Los estándares de mi código personal también pueden ser frustrantes, pero siempre siento que le estoy haciendo un favor al mundo / empresa / equipo al implementarlos. Así que no creo que intentes hacer demasiado: los resultados variarán de un lugar a otro, pero al menos estás haciendo el esfuerzo.

gws2
fuente
7

Esto parece un gran caso de plomo con el ejemplo .

Hay dos aspectos inherentes de la naturaleza humana que estás luchando:

  • A las personas creativas no les gusta el proceso.
  • A la mayoría de las personas no les gustan los juicios negativos externos sobre su calidad.

Es muy difícil combatir esto con conferencias, declaraciones de gestión o incluso lógica. Tienes que ganar aprovechando un aspecto alternativo de la naturaleza humana.

  • Las personas imitan el comportamiento de los mejores empleados.

Si los mejores empleados usan TDD y funciona, el proceso se expandirá. Si no lo hacen, no lo hará. Si necesita convencer a alguien, son los mejores 1 o 2 empleados.

MathAttack
fuente
Vale la pena señalar que sin estar ya en una cultura que abraza TDD, sus colegas no lo están impulsando a mejorar. Si ven una debilidad en su método, lo llamarán y dirán "para que nunca funcione". Para liderar con el ejemplo, debe invertir su propio tiempo y esfuerzo para mejorar su metodología.
perfeccionista
3

Pregúntales.

Usted dice que se les ha dicho a las personas y acepta que deberían escribir más pruebas. ¿Por qué no lo son?

Puede que (a menudo no lo sea) se trate de una simple motivación. Podrían olvidarse de ellos. Pueden sentirse presionados por el tiempo. Es posible que no sepan cómo escribir buenas pruebas. Pueden pensar que eres tan bueno que no necesitan hacerlo. Conocer la causa raíz lo ayudará a resolver mejor el problema.

Telastyn
fuente
66
En teoría es una buena idea, pero es difícil responder la pregunta. Entonces, si sabe que las pruebas unitarias son buenas, ¿por qué no las está usando? sin sonar como un imbécil, por ejemplo , no sé cómo o no tengo tiempo o soy inteligente, mi código debería funcionar . Esa situación normalmente pondría a la gente a la defensiva y obtendrías malos resultados.
R0MANARMY
2
No quiero señalar los "errores" de otras personas. Tal vez debería tener una conversación mientras estoy en privado, por ejemplo, tomar una cerveza o diez. La presión del tiempo no es realmente un punto. Tenemos un excelente horario con suficiente tiempo de amortiguación. (150% + estimado)
lurkerbelow
2

Uno pensaría que las pruebas unitarias serían la venta misma. No sé cómo funciona su empresa, pero cuando hay un problema durante un lanzamiento de producción, lo trabajamos hasta que se solucione. No importa si sucede a las 2 de la mañana un domingo por la mañana. Esto es muy raro para nosotros, pero cuando lo hace, apesta.

Comenzaría preguntándoles cuántas veces tuvieron que levantarse en medio de la noche para solucionar un problema importante que podría haberse encontrado fácilmente en las pruebas automatizadas. Esto no quiere decir que las pruebas automáticas lo arreglen todo, pero deberían ayudar a reducirlo.

El segundo gran vendedor es el ciclo de control de calidad. Antes del comienzo de TDD en mi empresa, promovíamos nuevos lanzamientos a QA para probar cada semana. Crearían una pila de errores en esa versión, corregimos esos errores y empujamos otra versión. Repita hasta que termine. El primer proyecto que hicimos TDD no requirió un impulso a QA hasta varias semanas después. Y la cantidad de errores encontrados ha sido muy, muy pequeña. 10% en comparación con un proyecto similar. ¿De todos modos tienes que compilar esas estadísticas para tu equipo?

El otro gran punto de venta fue cómo se veía el código después de que se adoptó TDD, era más fácil de leer, porque queríamos que fuera más fácil probarlo. Muestra una comparación entre el código escrito para pruebas unitarias y el código no escrito.

Finalmente, muéstreles cómo podrán refactorizar el código con confianza.

Tenga todo eso en mente cuando no tenga ganas de escribir exámenes. :)

bwalk2895
fuente
1

Me gustaría ampliar la respuesta de HLGEM , especialmente esta sección:

La siguiente razón es que con una gran base de código no probado existente, escribir pruebas probablemente parece abrumador, un trabajo interminable (como lavar y casi tan emocionante). Entonces, la naturaleza humana es pensar que es demasiado para enfrentar, así que lo omitiré.

He descubierto que el código que escribo con la intención de escribir pruebas es un código significativamente mejor que el código que escribo sin la intención de escribir pruebas; preguntándome ¿Cómo probaré esta función? obliga a un mejor diseño de todas y cada una de las funciones. (Menos dependencia de datos globales o semi-globales; IO separado de la computación; las funciones solo hacen una cosa; manejo de errores consistente; y así sucesivamente).

Intentar poner pruebas en código antiguo que no fue escrito teniendo en cuenta las pruebas puede ser más que frustrante.

sarnold
fuente
1

He usado algunas técnicas:

a) configurar una compilación automatizada. Cuando alguien rompe algo que usted probó, muéstrele cómo la prueba lo detectó y qué tan grave habría sido el error.

b) Realice proyectos complejos con pruebas (usted conduce). Esto mostrará cómo pocos errores existen en ese proyecto. Tuve un complejo proyecto de interacción con el servidor que comenzó a funcionar sin problemas. Nunca falló el control de calidad y todas las pruebas de integración se realizaron al 100% sin problemas. Ese sistema se hizo conocido como altamente estable y la administración general estaba contenta con él. Lo que haces en estas situaciones es presentar cómo las pruebas unitarias lo permitieron.

c) Tire de una persona a la vez. El que te escucha. Enfréntate a los errores y muestra cómo las pruebas exponen problemas profundos y difíciles. Esto ayuda. Nunca es una cosa fácil. Pero una vez que consigas un fanático, solo te ayudará. Es un efecto dominó.

usuario84575
fuente
c) se ve bien para mi caso
Nakilon
0

Hornear pruebas unitarias en el proceso. Si se muestra un error en la producción que es demasiado obvio para atrapar en la prueba de la unidad, entonces este tipo tiene la culpa. Asigna a las personas para que escriban cada prueba que hagan. Seleccione casos al azar y observe la ejecución de algunos casos cada semana. Al hacer pruebas unitarias, las personas preguntarán sobre los requisitos y eventualmente vincularán los requisitos con el desarrollo y, con suerte, desarrollarán el software que requiere y funciona :)

Ninguna posibilidad
fuente
Gracias por tu contribución. Declaró que escribir pruebas unitarias obliga al desarrollador a pensar un poco más sobre los requisitos, etc. Eso a veces es realmente un problema. La característica A está implementada y funcionando. QA le dice a dev que el caso de prueba x no funciona porque no ha pensado en los posibles efectos secundarios. Estamos utilizando la integración continua para hacer cumplir nuestras pruebas unitarias. Todas las pruebas se ejecutan si alguien registra algo. Por lo tanto, detectaríamos posibles efectos secundarios antes de enviarlo a QA / clientes.
lurkerbelow
1
Las pruebas unitarias son diferentes a las pruebas de integración. Creo que el desarrollador también es responsable de las pruebas de integración y la función de control de calidad sería asegurarse de que todo esté en orden (en la medida de la verificación que puedan realizar). Por supuesto, puede haber problemas en las versiones, piezas faltantes, distribución de código a los servidores, etc.
NoChance