¿Cuál es la sobrecarga real de TDD una vez que todo el equipo está acostumbrado?

24

Qué porcentaje de tiempo se ahorra y cuesta al hacer TDD.

Supongo que este porcentaje de cambios de costo y recompensa durante el ciclo de vida de un proyecto.

Me imagino que la fase inicial tiene un costo mucho más alto pero con pocas recompensas. Más adelante (durante la refactorización ) obtendrá el beneficio de sus pruebas.

Escuché que entre el 30 y el 50% de su tiempo está escribiendo pruebas unitarias. Sin embargo, eso no tiene en cuenta el tiempo ahorrado de escribir esas pruebas.

¿Cuál es la experiencia de todos con esto?

Wes

EDITAR ¿ Cuál es el tiempo ahorrado y el costo del tiempo? En la corrección de errores y refactorablity?

Wes
fuente
Escriba pruebas antes de codificar o escriba pruebas después, creo que la sobrecarga es insignificante ya que de cualquier manera escribe pruebas.
Chris
1
@Chris, cuando escribes pruebas primero diseñas la API por adelantado, en lugar de eso.
3
@ Thorbjørn: De acuerdo con su observación, aunque es completamente posible diseñar una API sin usar TDD, apenas una idea de último momento.
Robert Harvey
2
@ Steven: Sí, sé lo que es TDD. Es interesante que digas diseñar la API por adelantado. Eso me parece un buen enfoque. Nunca me ha convencido por completo la idea de que puedes "hacer crecer" una API escribiendo un montón de pruebas.
Robert Harvey

Respuestas:

8

He oído que entre el 30 y el 50% de su tiempo está escribiendo pruebas unitarias. Sin embargo, eso no tiene en cuenta el tiempo ahorrado

En mi experiencia, es más del 50%.

Una vez que ha escrito la prueba, la solución tiende a ser muy fácil. Por lo tanto, no creo que sea extraño pasar del 70% al 75% de su tiempo escribiendo pruebas, pero pasa mucho menos tiempo escribiendo el 'código de producción' (código que se está probando) y prácticamente no pasa tiempo en el depurador .

Cuanto antes encuentre un error, más barato será repararlo, y TDD lo ayudará enormemente. He trabajado en proyectos en los que pasé los últimos 2 meses (de un proyecto de 8 meses) reparando errores, y esa fase se eliminaría casi por completo con TDD.

Para mí, sin embargo, el valor real está en el mantenimiento. Heredar una base de código con pruebas lo hace tener menos miedo de alterarlo. Sientes que no rompiste nada cuando las pruebas aún pasan. Dado que no tiene miedo de hacer cambios, está dispuesto a refactorizar si algo no está bien. Lo que significa que el código se puede hacer más limpio, el diseño puede ajustarse mejor y, en teoría, se pueden aplicar cambios. Compare eso con el código vudú que todos tienen miedo de tocar.

Brad Cupit
fuente
Si las pruebas son buenas pruebas. Sin embargo, algunos son mejores que ninguno y, por lo general, se puede saber bastante rápido si la prueba es buena o no.
Michael K
1
entonces cree que hay ahorros reales tangibles en el tiempo. (2 meses) según su ejemplo, pero ¿cuánto tiempo habría pasado en las pruebas? Buena respuesta por cierto.
Wes
@Wes Es muy difícil saberlo. Escribo el código bajo prueba más rápido, pero paso mucho tiempo en las pruebas, lo que me ayuda a encontrar errores antes, lo que ahorra tiempo, pero no sé cuánto tiempo ahorró ya que no encontré el error ¡tarde! Personalmente, creo que TDD cuesta más a corto plazo, pero ahorra más a largo plazo. Cuanto más largo sea el proyecto, más se beneficia.
Brad Cupit el
Moví esto a mi respuesta acertada ahora.
Wes
15

Cada vez que ejecuta sus pruebas unitarias, se ahorra la cantidad de tiempo que le tomaría probar manualmente su código.

El 30% al 50% del tiempo que usted cita como requerido para escribir sus pruebas también se ve compensado en gran medida por los beneficios de tener un mejor diseño de software (comprobable).


Digamos que lleva cuatro veces más tiempo escribir una prueba automatizada que realizarla manualmente. Eso significa que la cuarta vez que ejecuta su prueba automatizada, se paga sola. Cada vez que ejecuta la prueba automatizada después de eso, es gratis.

Esto es válido tanto si la prueba es una prueba unitaria automatizada o una prueba funcional automatizada. No todas las pruebas funcionales se pueden automatizar, pero muchas de ellas sí. Además, la prueba automatizada es más confiable que una persona; ejecutará la prueba exactamente de la misma manera , siempre.

Tener pruebas unitarias significa que puede refactorizar la implementación subyacente de un método (por rendimiento u otras razones), y las pruebas unitarias verificarán que la funcionalidad del método no ha cambiado. Esto es especialmente cierto para TDD, donde la prueba unitaria especifica la funcionalidad del método.

Robert Harvey
fuente
No estoy convencido de que te guardes las pruebas manuales. TBH. Para asegurarte de que algo funciona funcionalmente, deberías seguir utilizando la regresión, al menos hasta donde yo sé.
Wes
66
Las pruebas unitarias son regresión. No estoy seguro de lo que estás diciendo.
Robert Harvey
2
Las pruebas unitarias y las pruebas funcionales son dos formas de prueba de regresión. Creo que Wes se está refiriendo a esto último.
Phil Mander el
@Phil Mander exactamente correcto. @Robert Harvey Me refería a pruebas funcionales, mi cerebro no encontró la palabra correcta. Aunque estoy bastante seguro de que mi subconsciente hizo lo mismo que usé la palabra funcionalmente allí: S Oh y buena edición, por cierto.
Wes
No creo que ejecutar la prueba exactamente de la misma manera cada vez sea ​​realmente positivo, ya que es posible pasar por alto constantemente encontrar problemas como ese.
Peter Ajtai el
5

TDD a menudo se mide en función de la calidad del código en lugar del tiempo y el costo invertido. Sin embargo, con una mejor calidad de código, los desarrolladores y las personas que trabajan con ellos pueden trabajar mejor (menos tiempo, menos costos, más felices, etc.). http://davidlongstreet.wordpress.com/2009/04/29/new-software-metric-wtfs-per-minute/

Escribir pruebas es excelente para ayudar a automatizar la verificación de requisitos funcionales y no funcionales. Un video que me convenció de adoptar TDD (en realidad BDD, TDD de alto nivel): http://video.google.com/videoplay?docid=8135690990081075324#

  • Escribir pruebas funcionales puede ayudar a detectar errores / problemas antes durante la fase de desarrollo . Suponga que tiene una base de código grande. Con las pruebas / especificaciones de la unidad , solo necesita ver "Todas las pruebas pasaron" / "2 pruebas fallaron, vea la línea xyz". Solo necesita un equipo de desarrolladores para desarrollar y probar. Sin pruebas unitarias / especificaciones , debe comparar manualmente las declaraciones impresas con las declaraciones esperadas, y rastrear manualmente qué métodos / clases tienen errores. Probablemente necesite dos equipos separados (desarrolladores y probadores) para hacer esto.

  • Las pruebas escritas ayudan a los desarrolladores a explicar el progreso y los problemas que enfrentan.

  • TDD ayuda a cumplir con el mantenimiento, la adaptabilidad y la flexibilidad del código. Alienta a los desarrolladores a escribir pequeños trozos comprobables, y ponerlos juntos en trozos comprobables más grandes. Al revés (parte de la práctica de refactorización) también funciona, con la condición de que hayamos escrito pruebas sólidas. Como resultado, podemos tener un código modular bien escrito.

Con TDD, nos complace saber cuándo:

  • un cliente solicita cambios en los requisitos (requisitos satisfactorios)
  • se descubren mejores formas de escribir código
  • los compañeros de equipo tienen sugerencias para mejorar el código
  • tenemos que explicar / pasar nuestro código a otras personas

TDD puede ser aburrido porque el proceso de desarrollo toma pequeños pasos y, por lo tanto, se vuelve muy predecible.

n193853
fuente
4

En nuestro caso, estimaría que está cerca del 40%. Sin embargo, no creo que hayamos pasado por una fase en la que fue más que esto. Tenemos un generador de código que escupe tanto un esqueleto de código que los desarrolladores desarrollan como un conjunto de pruebas que también se desarrolla. La mayor parte de nuestro esfuerzo de prueba se destina a rastrear (o crear) datos de prueba apropiados para garantizar que obtengamos una cobertura completa.

TMN
fuente
¿Es este un generador de código de cosecha propia, o un generador de código de código abierto que está disponible en la naturaleza?
Robert Harvey
Es una solución manual, basada en las clases .NET CodeDOM.
TMN
3

Las medidas importantes a largo plazo no son solo la calidad del código y la confianza del código, sino incluso más aún, no quemar al equipo haciendo pruebas sin sentido

las medidas a corto plazo serían el ROI de automatizar las pruebas

por ejemplo: la semana pasada realicé más de 1000 cambios de código debido a un cambio en la arquitectura interna, comencé el conjunto de pruebas automatizadas y me fui a dormir.

las pruebas tardaron 28 minutos en ejecutarse; Todos pasaron. La realización manual de las mismas 40+ pruebas de aceptación llevaría unas 6 horas.

Otro ejemplo: en una iteración anterior había engañado uno de los escenarios de prueba con un error sutil que las pruebas manuales probablemente no hubieran encontrado (las pruebas automatizadas realizan verificaciones de integridad de db que los probadores manuales casi nunca hacen). Tuve que ejecutar ese escenario de prueba unas 50 veces antes de que pudiera resolverlo y solucionarlo. La realización manual de las operaciones del escenario de prueba llevaría unos 50 minutos. Eso es 41.6 horas-hombre de trabajo ahorradas en un día

no hay forma de calcular por adelantado el ROI de las pruebas automáticas, porque no puede saber exactamente cuántas veces necesitará ejecutar las pruebas.

pero para mí, el ROI de las pruebas automatizadas es casi infinito

Steven A. Lowe
fuente
1
Oh eso está en un punto interesante. Pensé que las verificaciones de integridad de la base de datos deberían estar fuera de las pruebas unitarias. ¿Qué otras pruebas, aparte de las pruebas unitarias, ejecutas de forma automatizada?
Wes
1
@Wes: las pruebas en TDD se conocen como pruebas de "unidad", pero no dejes que ese nombre desafortunado limite su alcance. Su propósito es probar características . Una característica puede ser "la función foo siempre devuelve nulo" o puede ser "la latencia general del sistema bajo carga máxima debe ser inferior a 12 picosegundos".
Steven A. Lowe
0

Puede ayudar mucho restringir las pruebas unitarias a algoritmos complejos, casos en los que pueden generarse automáticamente y regresiones.

La prueba de componentes a menudo hace un gran trabajo para un código bastante trivial, además de cambiar la implementación es mucho más barato porque las pruebas solo se acoplan a la interfaz.

La cobertura completa con pruebas unitarias de grano fino tiene una gran sobrecarga para cambiar o refactorizar una implementación, que es exactamente lo que afirman que facilita.

hacendado
fuente