it-swarm-es.com

¿Cuáles son las desventajas de la programación de prueba primero?

Está de moda hoy en día. "Todos" lo recomiendan. Eso en sí mismo me hace sospechar.

¿Cuáles son algunas desventajas que ha encontrado al realizar el desarrollo de prueba primero (basado en pruebas)? Estoy buscando experiencias personales de profesionales expertos: puedo leer las reflexiones hipotéticas de un centenar de aspirantes en otras partes de Internet.

No pregunto porque estoy buscando odiar a TDD, sino porque es mi trabajo mejorar el proceso de desarrollo de software, y cuanto más podamos aprender sobre los problemas que enfrentan las personas, más posibilidades tenemos de mejorar el proceso.

48
Alex Feinman

Hay bastantes, pero las ventajas lejos son mayores que las desventajas.

Hay una curva de aprendizaje empinada.

Muchos desarrolladores parecen esperar que puedan ser eficientes con la programación de prueba primero desde el primer día. Desafortunadamente, toma mucho tiempo ganar experiencia y programar a la misma velocidad que antes. No puedes evitarlo.

Para ser más específicos, es muy fácil equivocarse. Muy fácilmente (con muy buenas intenciones) puede terminar escribiendo un montón de pruebas que son difíciles de mantener o probar cosas incorrectas. Es difícil dar ejemplos aquí: este tipo de problemas simplemente requieren experiencia para resolverlos. Debe tener una buena sensación de separar las preocupaciones y diseñar para la comprobabilidad. Mi mejor consejo aquí sería hacer programación de pares con alguien que conozca TDD realmente bien.

Haces más codificación por adelantado

Test-first significa que no puedes saltarte las pruebas (lo cual es bueno) y significa que terminarás escribiendo más código por adelantado. Esto significa más tiempo. De nuevo, no puedes evitarlo. Usted es recompensado con un código que es más fácil de mantener, extender y generalmente menos errores, pero lleva tiempo.

Puede ser una venta difícil para los gerentes

Los administradores de software generalmente solo se preocupan por los plazos. Si cambia a la programación de prueba primero y de repente toma 2 semanas para completar una función en lugar de una, no les va a gustar. Definitivamente esta es una batalla que vale la pena pelear y muchos gerentes están lo suficientemente informados como para obtenerla, pero puede ser una venta difícil.

Puede ser una venta difícil para otros desarrolladores.

Dado que hay una curva de aprendizaje empinada, no a todos los desarrolladores les gusta la programación de prueba primero. De hecho, supongo que a la mayoría de los desarrolladores no les gusta al principio. Puede hacer cosas como la programación de pares para ayudarlos a ponerse al día, pero puede ser una venta difícil.

Al final, las ventajas son mayores que las desventajas, pero no ayuda si ignora las desventajas. Saber de qué se trata desde el principio le ayuda a negociar algunas, si no todas, las desventajas.

41
Jaco Pretorius

Test-first asume que está escribiendo código que es:

  • comprobable de manera unitaria
  • que lo que está desarrollando tiene un enfoque obvio y no requerirá una amplia creación de prototipos o experimentación
  • que no necesitará refactorizar demasiado o que tiene tiempo para reescribir repetidamente cientos o miles de casos de prueba
  • nada está sellado
  • todo es modular
  • todo es inyectable o burlable
  • que su organización asigna un valor lo suficientemente alto a los defectos bajos para justificar el sumidero de recursos
  • que hay algo de beneficio para probar a nivel de prueba unitaria

Si su proyecto no cumple con esos requisitos, tendrá dificultades. Los promotores de TDD no tienen buenas respuestas a esta otra para sugerirle que rediseñe su producto para que se ajuste mejor a esas líneas. Hay situaciones en las que eso es imposible o indeseable.

En la práctica, también puedo tener un gran problema con las personas que piensan que las primeras pruebas prueban realmente algo sobre la función correcta del programa. En muchos casos esto no es cierto, pero incluso en los casos en que es cierto, está lejos de ser una imagen completa de la corrección. Las personas ven cientos de pruebas aprobadas y suponen que es seguro realizar menos pruebas ya que antes de la TDD solo hacían unos cientos de casos de prueba de todos modos. En mi experiencia, TDD significa que necesita tener aún más pruebas de integración, ya que los desarrolladores también tendrán la falsa seguridad y el dolor de cambiar todas las pruebas para hacer un gran redactor puede llevar a los desarrolladores a hacer soluciones interesantes.

Ejemplos:

Mi mejor ejemplo personal es cuando escribo código de seguridad para asp.net. Si están destinados a ejecutarse en un entorno hostil desde la configuración de la máquina, están guardados, firmados y sellados, y debido a que se ejecutan contra IIS objetos de Dios, es muy difícil burlarse de ellos) correctamente. Agregue algunas restricciones para el rendimiento y el uso de la memoria y rápidamente perderá la flexibilidad de usar objetos de marcador de posición en las áreas restantes.

Cualquier tipo de microcontrolador u otro código de entorno de bajos recursos puede no ser posible hacer verdaderamente OO diseño de estilo ya que las abstracciones no se optimizan y tiene límites de recursos bajos. Lo mismo puede decirse de Rutinas de alto rendimiento en muchos casos también.

36
Bill

El mayor inconveniente que he visto no es con el TDD en sí, sino con los profesionales. Adoptan un enfoque dogmático y fanático donde todo debe ser probado . A veces (muchas veces eso es), eso no es necesario. Además, podría no ser práctico (es decir, presentar una organización a TDD).

Un buen ingeniero encuentra compensaciones y aplica el equilibrio correcto de cuándo/dónde/cómo aplicar primero la prueba. Además, si se encuentra constantemente pasando mucho más tiempo desarrollando pruebas en lugar del código real (por un factor de 2-3 o más), está en problemas.

En otras palabras, sea pragmático y razonable con TDD (o cualquier cosa en el desarrollo de software para el caso).

26
luis.espinal

Comencé a hacer TDD a principios de agosto de 2009 y convencí a toda mi compañía para que lo cambiara en septiembre/octubre de 2009. Actualmente, todo el equipo de desarrollo está completamente convertido, y comprometer el código no probado al repositorio se considera una mala cosa. Nos ha estado funcionando muy bien, y no puedo imaginar volver a la codificación de vaqueros.

Sin embargo, hay dos problemas que son bastante notables.

El conjunto de pruebas debe mantenerse

Cuando se toma en serio la TDD, terminará escribiendo lotes de pruebas. Además, lleva algo de tiempo y experiencia darse cuenta de cuál es la granularidad correcta de las pruebas (exagerar es casi tan malo como exagerar). Estas pruebas también son código , y son susceptibles a bitrot. Esto significa que debe mantenerlos como todo lo demás: actualícelo cuando actualice las bibliotecas de las que dependen, refactorice de vez en cuando ... Cuando realice grandes cambios en su código, muchas pruebas quedarán desactualizadas o incluso completamente equivocado. Si tiene suerte, simplemente puede eliminarlos, pero muchas veces terminará extrayendo los bits útiles y adaptándolos a la nueva arquitectura.

Pruebas de abstracciones de fuga de vez en cuando

Estamos utilizando Django, que tiene un marco de prueba bastante bueno. Sin embargo, a veces hace suposiciones que están ligeramente en desacuerdo con la realidad. Por ejemplo, algunos middleware pueden romper las pruebas. O, algunas pruebas hacen suposiciones sobre un backend de almacenamiento en caché. Además, si está utilizando una base de datos "real" (no SQLite3), la preparación de la base de datos para las pruebas llevará mucho tiempo. Claro, puede (y debe) usar SQLite3 y una base de datos en memoria para las pruebas que realiza localmente, pero algunos códigos se comportarán de manera diferente dependiendo de la base de datos que use. Es imprescindible configurar un servidor de integración continua que se ejecute en una configuración realista.

(Algunas personas le dirán que debe burlarse de todas las cosas, como la base de datos, o sus pruebas no son "puras", pero eso es solo ideología hablando. Si comete errores en su código de burla (y créame, lo hará), su traje de prueba será inútil.)

Dicho todo esto, los problemas que describí comienzan a notarse solo cuando está bastante avanzado con TDD ... Cuando recién está comenzando con TDD (o trabajando en proyectos más pequeños), la refactorización de pruebas no será un problema.

6
Ryszard Szopa

Para mí, hay algún problema psicológico profundo con las pruebas cada vez que trato de aplicarlas ampliamente, como en TDD: si están allí, codifico descuidadamente porque confío en que las pruebas detectarán cualquier problema. Pero si no hay pruebas para proporcionar una red de seguridad, codifico cuidadosamente, y el resultado es invariablemente mejor que con las pruebas.

Tal vez solo soy yo. Pero también he leído en alguna parte que los automóviles con todo tipo de campanas y silbatos de seguridad tienden a chocar más (porque los conductores saben que las características de seguridad están ahí), por lo que tal vez sea algo para reconocer; TDD puede ser incompatible con algunas personas.

4
Joonas Pulakka

Una situación en la que prueba primero realmente se interpone en mi camino es cuando quiero probar rápidamente alguna idea y ver si puede funcionar antes de escribir una implementación adecuada.

Mi enfoque es normalmente:

  1. Implemente algo que se ejecute (prueba de concepto).
  2. Si funciona, consolide agregando pruebas, mejorando el diseño, refactorizando.

A veces no llego al paso 2.

En este caso, usar TDD ha resultado tener más desventajas que ventajas para mí:

  • Escribir pruebas durante la implementación de la prueba de concepto solo me ralentiza e interrumpe mi flujo de pensamientos: quiero entender una idea y no quiero perder el tiempo probando detalles de mi primera implementación aproximada.
  • Puede llevar más tiempo averiguar si mi idea vale algo o no.
  • Si resulta que la idea era inútil, tengo que tirar mi código y mis pruebas unitarias bien escritas.

Entonces, cuando tengo que explorar algunas ideas nuevas, no uso TDD y solo presento pruebas unitarias cuando tengo la sensación de que el nuevo código está llegando a alguna parte.

2
Giorgio

Desventajas o costos de TDD

Nota: Hay una variedad de diferentes tipos de TDD. Independientemente de la unidad, BDD, ATDD u otras variantes, muchas de las dificultades persisten

Efectos secundarios

Ya sea que se trate de burlas, accesorios o pruebas funcionales, las dependencias en estados o sistemas externos son a menudo la fuente de mayor complejidad en las pruebas, confusión en la forma de prueba y el mayor riesgo de equivocarse. Algunos problemas que he visto:

  • Burlándose: olvídate de afirmar el orden de las llamadas
  • Burlándose: el simulacro no coincide con una llamada o respuesta real
  • Fixture: la prueba se basa en datos poco realistas, enmascarando otros problemas
  • Fixture: prueba un estado imposible en producción
  • Funcional: fallas de compilación falsas debido a que el sistema dependiente no está disponible temporalmente
  • Funcional: la velocidad de la prueba es muy lenta

Tendrá que cambiar su enfoque de codificación, para algunos será un cambio drástico.

Diferentes personas codifican de maneras muy diferentes. En TDD, debe comenzar con una prueba que afirme un comportamiento específico y luego implementarla para que la prueba pase. He visto y era un programador cuya programación no conducía a TDD. Me tomó alrededor de 2 meses cuando comencé a acostumbrarme a cambiar mi enfoque de desarrollo.

Se necesita tiempo para comprender lo que le interesan las pruebas y lo que no le interesan las pruebas.

Cada equipo debe tomar una decisión explícita sobre dónde quieren trazar la línea en las pruebas. Qué cosas valoran que quieren probar y qué no. A menudo es un proceso doloroso aprender a escribir buenas pruebas, y lo que realmente te interesa de las pruebas. Mientras tanto, el código continuará en un estado de cambio hasta que haya coherencia tanto en el estilo como en el enfoque.

Prueba de unidad específica: refactores grandes

Un refactor grande o fundamental de una base de código significativa con decenas de miles de pruebas unitarias generará un costo enorme para actualizar todas las pruebas. Esto a menudo se manifestará en un rechazo en contra de hacer una refactorización, incluso si es lo correcto, simplemente debido al costo asociado con hacerlo.

1
dietbuddha

Mi analogía es barreras en una pista Scalextric. Si te los pones, te vuelves mucho menos cauteloso.

Las personas también obtienen un poco de cadete de espacio con respecto a sus pruebas, ya que corren bien, creen que el código está completamente probado, mientras que solo es el comienzo del proceso de prueba.

En mi opinión, TDD es un trampolín para BDD. Una serie de pruebas que se ejecutan realmente no ayuda a los desarrolladores de soporte sin saber lo que hacen las pruebas. Con BDD, el resultado de la prueba está en inglés, que documenta las pruebas y, por lo tanto, crea una comprensión del sistema.

0
Robbie Dee