Cómo explicar el valor de las pruebas unitarias

30

Quiero presentar el concepto de pruebas unitarias (y pruebas en general) a mis compañeros de trabajo; en este momento no hay pruebas en absoluto y las cosas se prueban realizando las tareas a través de la interfaz de usuario para ver el resultado deseado. Como puede imaginar, el código está estrechamente vinculado a la implementación exacta, incluso dando como resultado que el código que debería estar en una clase y reutilizarse en todo el sistema se copie y pegue en todos los métodos.

Debido a los requisitos modificados, me han pedido que modifique un módulo que escribí anteriormente y que está bastante acoplado (no tanto como me gustaría, pero lo mejor que puedo obtener sin tener que introducir muchos otros conceptos). He decidido incluir un conjunto de pruebas unitarias con mi código revisado para "probar" que funciona como se esperaba y demostrar cómo funciona la prueba; No sigo TDD verdadero ya que parte del código ya está escrito, pero espero seguir algunos conceptos de TDD para el nuevo código que tendré que crear.

Ahora, inevitablemente, estoy seguro de que me preguntarán por qué me lleva más de un día o dos escribir el código, ya que partes de lo que interactuaré ya existen en el sistema (aunque sin ninguna prueba y muy estrictamente acoplado), y cuando verifico el código, me preguntarán qué es este proyecto de "Pruebas". Puedo explicar los conceptos básicos de las pruebas, pero no puedo explicar los beneficios reales de una manera que los demás entenderían (porque piensan que las pruebas requieren que ejecute la aplicación usted mismo, ya que a menudo la interfaz de usuario real es importante para determinar si la función "funciona" " o no). No entienden la idea del acoplamiento flojo (claramente evidente por el hecho de que nada está acoplado libremente; ni siquiera hay interfaces fuera del código que he escrito), así que tratar de usar eso como un beneficio probablemente me haría ganar un "¿Eh?" tipo de aspecto, y una vez más, no puedo estar tan suelto como me gustaría sin tener que volver a trabajar varios módulos existentes y probablemente introducir algún tipo de contenedor IoC, que se consideraría como una pérdida de tiempo y no "programación".

¿Alguien tiene alguna sugerencia sobre cómo puedo señalar este código y decir "Deberíamos comenzar a crear pruebas unitarias" sin parecer ya sea condescendiente (por ejemplo, "Escribir pruebas lo obliga a escribir un buen código", lo que probablemente se interpretaría como código excepto que el mío es malo ) o sin que parezca una pérdida de tiempo que no agrega ningún valor real?

Wayne Molina
fuente
1
Esto suena como el momento en que le pregunté al "experto en la base de datos" por qué la información de la tarjeta de crédito era A. sin etiqueta y B. Por qué el campo del número de teléfono era nvarchar (MAX) y C. Por qué no había relaciones entre ninguna de las tablas. Simplemente no lo entendió.
The Muffin Man
1
(esta es una respuesta sarcástica, es una broma ) -> (A) Si se rompe algo en su servidor de base de datos, tiene problemas más grandes. (B) El almacenamiento de datos es barato, y qué pasaría si uno quisiera almacenar metadatos dentro de un campo. (C) NoSQL baby;) ( Nuevamente déjame repetir que estoy bromeando )
Darknight
Hay un capítulo completo sobre esto en el gran The Art of Unit Testing .
StuperUser
66
@Wayne, cada vez que leo una de tus preguntas, estoy convencido de que necesitas encontrar un nuevo trabajo. Son una reliquia obsoleta y pesada en el desarrollo de software y tú no lo eres. Si se abre una ventana, salta hacia ella y no mires hacia atrás.
maple_shaft
2
@WayneM, Salga. Seriamente.
AK_

Respuestas:

18

Quiero presentar el concepto de pruebas unitarias (y pruebas en general) a mis compañeros de trabajo

Creo que sería mejor comenzar desde el lado práctico, no conceptual. Por supuesto, si encuentra durante una discusión informal que sus compañeros de trabajo y / o la gerencia están interesados ​​en escuchar sobre las pruebas unitarias, mucho mejor, entonces puede buscar en Google algunas experiencias / pruebas concretas de la web, organizar una breve capacitación, etc. Sin embargo, por lo que describe, parece que sus compañeros de equipo no están muy abiertos a esta nueva idea extraña.

En tal situación, simplemente comenzaría a escribir mis pequeñas pruebas unitarias sin tratar de explicarle demasiado a nadie primero. Agregue un par de ellos cada vez que cambie el código, sin tratar de cubrir todo el código (lo que tomaría una cantidad excesiva de tiempo). Idealmente, si logro lograr un buen equilibrio, para cuando se den cuenta de que estoy escribiendo pruebas unitarias, es posible que ya tenga un conjunto de pruebas sustancial y algunos resultados concretos que mostrar (como "con este caso de prueba logré detectar un error introducido por el cambio de la semana pasada, que de otro modo se habría deslizado a QA / producción "). Eso demostrará el valor de las pruebas para cualquier desarrollador serio.

Después de eso, estoy en una buena posición para comenzar a explicar los beneficios a largo plazo de las pruebas unitarias, como

  • demuestra que el código funciona, en cualquier momento, en cualquier lugar, de forma instantánea y automática, lo que a su vez
  • da confianza al refactorizador, lo que resulta en un diseño mejorado y una mejor mantenibilidad
  • y si algo se rompe, las pruebas unitarias le brindan (casi) retroalimentación instantánea, a diferencia de la latencia de varios días o semanas si el error es detectado por un departamento de control de calidad separado. Lo que generalmente le permite corregir el error en segundos, en lugar de depurar durante horas / días, en un código que hace mucho tiempo se cayó de su memoria a corto plazo.

Vea también este hilo relacionado: Prueba de unidad automatizada, prueba de integración o prueba de aceptación .

Y uno anterior de SO: ¿Qué son las pruebas unitarias?

Péter Török
fuente
44
+1 para el aspecto práctico. Hicimos esto en nuestro 50+ dev. comprar y se está poniendo de moda. Cada vez que tenemos un desarrollador más. escribiendo las pruebas, están enganchados.
cerveza
Lo malo es que está escribiendo las pruebas, pero sus compañeros de trabajo no las conocen y cambiarán algo en el código de producción que hará que las pruebas fallen, cancelando todos sus esfuerzos :(
Igor Popov
¿Al principio revisó las pruebas o las guardó para usted? Me imagino que un revisor no estaría encantado si empiezo a revisar los archivos de prueba sin la aprobación de mi jefe
Frode Akselsen
12

Re-factorizar sin miedo

Como un ángulo ligeramente diferente, TDD le permite "re-factorizar sin miedo", y este es un beneficio clave que puede vender a su equipo. Impide que los desarrolladores se digan a sí mismos:

  • "No quiero tocar este código porque me temo que lo romperé"
  • "No quiero escribir nuevas funcionalidades en este código porque no sé cómo funciona"
  • "Secretamente, tengo miedo de ese código"

Podría insistir más, pero este es un terreno bien cubierto como el Tío Bob en TDD y Martin Fowler en TDD .

Dependencias

Oh, agregaré una cosa más. Les mostrará cómo TDD fuerza un buen diseño que le permite lidiar limpiamente con las dependencias.

Bob: "¡Oh, c% ^ p! Los jefes simplemente nos obligaron a todos a usar MS SQL Server 2008" Jane: "Está bien, el daño se minimizó porque DIMOS nuestro origen de datos y nuestras clases DAO, estoy muy contento de que TDD haya alentado nosotros por ese camino ".

Martijn Verburg
fuente
4

Mientras trabajamos en el código fuente que no tiene pruebas automáticas, tenemos que trabajar con mucho cuidado y necesitamos más revisiones para mantenernos seguros de que ese tipo de cambios que estamos haciendo no rompe ninguna de las funcionalidades existentes.

Cuando tengamos buenos casos de prueba automatizados, las consecuencias serán un desarrollo más rápido, seguro e intrépido (puede ser la corrección de errores, la mejora o la refactorización).

Dhanunjai
fuente
4

Haz las matematicas

  • t mt = el tiempo requerido para probar manualmente todo lo que posiblemente pueda afectar
  • t wt = el tiempo requerido para escribir las pruebas
  • k = la cantidad de veces que probablemente tendrá que probar todo antes de lanzar el nuevo código

    si (t wt <t mt ) o (t wt <(k * t mt )) es obvio: escribir las pruebas acelerará el desarrollo.

de lo contrario, mire la relación (t wt / (k * t mt )). Si es un número muy grande, espere otra oportunidad; de lo contrario, justifíquese con los beneficios de la prueba de regresión.

Nota: Sugiero en este punto probar solo las características, no las unidades , mucho más fácil de justificar y comprender, y posiblemente menos trabajo con un valor más alto que las simples pruebas unitarias al refactorizar.

Nota 2: el tiempo que lleva ejecutar las pruebas no importa , ya que están automatizadas. Puede hacer algo más productivo mientras se ejecutan las pruebas, a menos que las pruebas tarden tanto en ejecutarse que le harán perder el plazo. Lo cual es raro.

Steven A. Lowe
fuente
Te doy un +1, ¡pero esa matemática da miedo!
Wayne Molina
@Wayne son solo los subíndices, son intimidantes. ¡Pero la programación no es para mariquitas! ;-)
Steven A. Lowe
1

Una sugerencia si es una tienda de Microsoft: encuentre alguna documentación en MSDN que recomiende pruebas unitarias o golpes sueltos como mejor práctica (estoy seguro de que hay varias instancias de esto ) y apúntela si hay conflictos.

Puede sonar como una forma grosera de hacer las cosas, pero he descubierto que usar el término 'mejores prácticas' lo llevará muy lejos, especialmente con la administración.

aceinthehole
fuente
1

Como siempre recomiendo, si conoce una buena práctica, la mejor manera de introducirla suavemente en su entorno sería, por supuesto, comenzar a hacerlo usted mismo y luego, en algún momento, algunos de sus compañeros de trabajo verán los beneficios y recogerlo

La palabra clave aquí es evolución, no revolución.

Jas
fuente