unit-testing - unit testing laravel
¿Es la prueba de unidad una mala idea durante la beta/prototipado? (15)
¿Alguno de ustedes también encontró que TDD puede ser una molestia si está creando un prototipo de algo / construyendo una versión beta?
Tengo .. Toneladas de veces :)
¿TDD va mucho más naturalmente de la mano con algo donde las especificaciones son más fijas, o donde los desarrolladores tienen más experiencia en el lenguaje y las tecnologías?
Realmente no. TDD funciona bastante bien con los requisitos cambiantes, pero TDD es realmente para garantizar un diseño estable e impulsado por contrato: dos cosas que los prototipos no necesitan tanto.
¿O he hecho algo fundamentalmente malo?
No se ve así :) Acabas de ver que TDD consiste en otras cosas además de árboles dorados.
Comenzamos con un nuevo proyecto que introdujo muchas tecnologías nuevas con las que no estábamos familiarizados y una arquitectura en la que no tenemos mucha práctica. En otras palabras, las interfaces e interacciones entre las clases de servicio, etc. Los edificios son bastante volátiles, y más aún debido a los comentarios internos y de los clientes. A pesar de que siempre me he sentido frustrado por las especificaciones en constante movimiento, considero que esto es, hasta cierto punto, una parte necesaria de la construcción de algo que nunca antes construimos: si nos limitamos al diseño y el alcance originales, el producto final probablemente sería Mucho menos innovador y útil de lo que se está convirtiendo.
También introduje el desarrollo dirigido por pruebas (TDD), ya que los beneficios están bien documentados y, conceptualmente, me encantó la idea. Dos cosas nuevas más que aprender, NUnit y burlas, pero ver todos esos círculos verdes hizo que todo valiera la pena.
Sin embargo, con el tiempo, esos cambios constantes en el diseño parecían significar que pasaba mucho más tiempo cambiando mis pruebas que escribiendo el código en sí. Solo por esta razón, he vuelto a las viejas formas de prueba, es decir, no automatizadas.
Si bien no tengo dudas de que la aplicación sería mucho más robusta con cientos de excelentes pruebas de unidades, encontré que la compensación de tiempo para lanzar el producto es en su mayor parte inaceptable. Mi pregunta es, entonces, ¿alguno de ustedes también encontró que TDD puede ser una molestia si está creando un prototipo de algo / construyendo una versión beta? ¿TDD va mucho más naturalmente de la mano con algo donde las especificaciones son más fijas, o donde los desarrolladores tienen más experiencia en el lenguaje y las tecnologías? ¿O he hecho algo fundamentalmente malo?
Tenga en cuenta que no estoy intentando criticar a TDD aquí, simplemente no estoy seguro de que siempre sea la mejor opción para todas las situaciones.
Sin embargo, con el tiempo, esos cambios constantes en el diseño parecían significar que pasaba mucho más tiempo cambiando mis pruebas que escribiendo el código en sí.
Escribo (y ejecuto) pruebas automatizadas de la E / S del sistema. La E / S del sistema depende de los requisitos funcionales, y no cambia cuando cambia la implementación del sistema, por lo que puedo refactorizar la implementación sin cambiar las pruebas automatizadas: ¿debería una aplicación de prueba interna, o solo probar el comportamiento público?
"Sin embargo, con el tiempo, esos cambios constantes en el diseño parecían significar que pasaba mucho más tiempo cambiando mis pruebas de lo que estaba escribiendo el código".
Bueno. Debes pasar mucho tiempo en la prueba. Es importante, y es cómo demuestras que tu código es correcto. "Menos código que prueba" es un buen punto de referencia.
Eso significa que estaba escribiendo pruebas efectivas que demostraron sus expectativas para la tecnología subyacente.
Es posible que desee considerar hacer esto.
Algunas pruebas son características "esenciales" o "básicas" o "duraderas" de la aplicación, independientemente de cualquier elección de tecnología. Centrarse en estos. El nunca debe cambiar.
Algunas pruebas confirman la tecnología o las opciones de implementación. Estos cambian todo el tiempo. Tal vez debería separarlos para que los cambios de tecnología lleven a cambios enfocados aquí.
Al hacer prototipos, diría que depende del tipo de prototipos. En la creación de prototipos evolutivos, donde el prototipo evoluciona hacia la aplicación final, utilizaría las pruebas unitarias lo antes posible. Si está utilizando prototipos desechables, no me molestaría con las pruebas unitarias: la aplicación final no será como el prototipo.
No estoy seguro de lo que quiere decir con "beta", ya que una beta es casi un producto terminado. Tan pronto como comience a trabajar en el código que se enviará o que tiene potencial para ser enviado, asegúrese de que todo esté bien probado.
Ahora, el desarrollo basado en pruebas puras puede ser extremo, pero es importante asegurarse de que todo el código enviable se pruebe lo más posible, a nivel de unidad, integración y sistema.
Cuando me pongo en contacto con una nueva tecnología, normalmente escribo un par de pruebas que utilizo como base del prototipo. La principal ventaja aquí es que me permite acostumbrarme a la tecnología en partes pequeñas y digeribles y que documente mi progreso en la única forma válida de documentación: el código.
De esa manera, puedo probar las suposiciones (¿qué sucede cuando persisto una cadena vacía en una base de datos? DB2 devolverá una cadena vacía, Oracle devolverá NULL) y me aseguro de que no cambien mientras trabajo en el prototipo.
Piense en este trabajo como muchos prototipos diminutos, todo en un par de pruebas unitarias.
Ahora el diseño de mi producto cambiará con el tiempo, pero estas pruebas de picos siguen siendo válidas: el marco subyacente no cambia solo porque ahora busco una solución diferente. De hecho, estas pruebas me permitirán migrar a la próxima versión de la tecnología, ya que sonarán una alarma cuando una de las suposiciones que he estado usando haya cambiado. De lo contrario, tendría que seguir con la versión actual o ser muy cuidadoso con cualquier actualización, ya que no podría estar seguro de qué se rompería.
Descubrí que los primeros resultados de las pruebas minuciosas arrojan muchos códigos y una sensación de vacío en la boca del estómago.
Pruebe lo que necesita ser probado y no una línea de código más. Cuando descubras cuánto es eso, avísame.
En el desarrollo ágil, existe el concepto de "pico": una investigación profunda pero estrecha de una solución o una tecnología. Una vez que se sienta cómodo con cómo deberían funcionar las cosas, vuelva a comenzar con una nueva implementación con un nivel de calidad superior.
Hay un problema con el software etiquetado como "beta": de repente, terminas con algo que no está diseñado para la producción como una parte vital de tu aplicación y no tienes tiempo para rehacerlo. Esto probablemente volverá y te morderá más adelante. Un prototipo debe ser realmente un prototipo, ni más ni menos.
La creación de prototipos está destinada a ser utilizada para la exploración "¿Funcionaría este tipo de cosas"?
Así que no hay necesidad de pruebas. ¡PERO! ¡Deseche siempre su prototipo y codifique desde la zona cero!
La respuesta corta es que TDD es muy valioso para las versiones beta, pero puede ser menos para la creación de prototipos.
Creo que es muy importante distinguir entre las versiones beta y la creación de prototipos.
Una versión beta es esencialmente una versión de producción que aún está en desarrollo, por lo que definitivamente debería usar TDD en ese escenario.
Un prototipo / prueba de concepto es algo que se construye con la intención expresa de desecharlo una vez que haya obtenido las respuestas que deseaba.
Es cierto que los gerentes de proyecto tenderán a presionar para que el prototipo se use como base para el código de producción, pero es muy importante resistir eso. Si sabe que eso no es posible, trate el código prototipo como lo haría con su código de producción, porque sabe que se convertirá en su código de producción en el futuro, y eso significa que también debe usar TDD con él.
Cuando estás aprendiendo una nueva tecnología, la mayoría de los ejemplos de código, etc., no se escriben teniendo en cuenta las pruebas de unidad, por lo que puede ser difícil traducir la nueva tecnología a la mentalidad de prueba de unidad. Definitivamente se siente como una gran sobrecarga.
Sin embargo, en mi experiencia, las pruebas unitarias a menudo realmente te obligan a ampliar los límites de la nueva tecnología que estás aprendiendo. Muy a menudo, necesita investigar y aprender todos los diferentes ganchos que proporciona la nueva tecnología, ya que necesita poder aislar la tecnología a través de DI o similar.
En lugar de solo seguir el camino trillado, las pruebas unitarias frecuentemente te obligan a aprender la tecnología con mucha más profundidad, por lo que lo que se siente como sobrecarga es en realidad un prototipo más profundo, uno que a menudo es más valioso, porque cubre más terreno .
Personalmente, creo que la prueba de unidad de una nueva tecnología es una gran herramienta de aprendizaje.
Los síntomas que parece experimentar con respecto a la capacidad de mantenimiento de la prueba son un poco ortogonales, creo. Sus pruebas pueden ser Overspecified , que es algo que puede suceder igual de bien cuando se trabaja con tecnologías conocidas (pero creo que probablemente sea más fácil caer en esta trampa cuando también está aprendiendo una nueva tecnología al mismo tiempo).
El libro xUnit Test Patterns describe el antipatterno Overspecified Test y proporciona una gran cantidad de pautas y patrones que pueden ayudarlo a escribir más pruebas de mantenimiento.
Lo que normalmente hago para este código de creación de prototipos es escribirlo sin pruebas (o no muchas), pero hacer el trabajo bajo mi src / test / java o donde sea que esté poniendo mi código de prueba. De esa manera, no lo pondré inadvertidamente en producción. Si hay algo que he hecho un prototipo que me gusta, entonces crearé algo en src / main / java (mi código de barra) y lo TDD, extrayendo el código del prototipo pieza por pieza a medida que agrego pruebas.
No tengo una receta para usted, pero sí tengo un diagnóstico:
Si alguna vez terminas en un depurador, deberías haber tenido más pruebas . Incluso en los primeros prototipos, quieres que el código que escribas funcione, ¿verdad? Si no hago TDD, y me encuentro con un error, es difícil actualizar las pruebas de las unidades para encontrar el error. Es tentador ir al depurador. Por lo tanto, apunto mis esfuerzos de TDD para producir un conjunto suficientemente bueno de pruebas para que no necesite el depurador. Hacer esto bien requiere mucha práctica.
Si quiere refactorizar pero no lo hace por riesgo, debería haber tenido más pruebas . Si voy a trabajar con algún código durante más de un par de horas, quiero refactorizar para mantener mi velocidad alta. Si dudo en refactorizar, esto perjudicará mi productividad, así que hago todo lo posible para que la refactorización sea segura y fácil. Una vez más, una buena selección de pruebas es exactamente lo que necesito.
Para prototipos puros, como la gente ha dicho, no es tan útil. Pero a menudo un prototipo tiene elementos de la aplicación que seguirán.
A medida que lo construyes, ¿cuáles son los conceptos sólidos que esperas que continúen? ¿Cuáles son los modelos de dominio clave? Tiene sentido construir pruebas alrededor de estos. Luego, proporcionan una base sólida sobre la cual explorar ideas. Al tener parte del código base sólido y probado, le permite ir más lejos con el prototipo de lo que podría sin pruebas.
Siempre es un balance de elegir las cosas correctas para probar cuándo. Parece que de tu descripción estás adoptando muchas cosas nuevas a la vez; a veces esto puede ser demasiado y necesitas retirarte un poco para optimizar tu progreso.
Sería cauteloso al descartar TDD cuando se realizan prototipos. Principalmente porque los prototipos tienden (pero no siempre) a evolucionar hacia el producto final. Si puede estar seguro de que los prototipos se descartan una vez que hayan establecido para qué se utilizaron, entonces puede estar un poco más relajado. Sin embargo, si existe la posibilidad de que el prototipo evolucione hacia el producto final, o partes del código se incorporen al producto final, entonces se esforzará por seguir los principios de TDD.
Esto no solo hace que su código sea más comprobable, sino que, lo que es más importante (en mi opinión) lo alienta a seguir los buenos principios de diseño de software.
Si en realidad es un prototipo y lo vas a tirar cuando hayas terminado, toma la ruta que te lleve a esa fase. Pero, pregúntese, ¿con qué frecuencia se desechan sus prototipos en comparación con la frecuencia con que se deslizan en su producto final?
Hubo una buena presentation en JavaOne en TDD. Uno de los resultados realmente buenos fue que tendías a entender tus requisitos reales mucho, mucho mejor cuando tenías que crear pruebas para cumplirlos. Esto se suma a todos los beneficios de refactorización y calidad del código que se incluyeron en el enfoque.
- Tener una hoja de ruta con una X en movimiento es frustrante. TDD o no TDD ... "tener que pasar la mayor parte del tiempo cambiando las pruebas en lugar del código" indica que las especificaciones se modificaron radicalmente o simplemente se burló usted mismo de las "pruebas frágiles". Necesitaría más información tuya para hacer más comentarios.
- Spike / Prototyping significa tratar de construir algo como prueba de concepto o validación de un diseño. Con esta definición, diría que no es necesario TDD su programa porque su principal objetivo es aprender / reducir las incógnitas. Una vez que hayas hecho eso, debes tirar tu proto y construir tu versión de producción con pruebas automatizadas (usa TDD ahora). Usted envía estos al cliente no ''prototipos probados''
- Sin embargo, si las pruebas manuales le han funcionado bien, continúe con ellas. Me gusta demostrarme a mí mismo ya los demás que mi código funciona con solo presionar un botón: evitar el aburrimiento humano de las tareas repetitivas y realizar pruebas exhaustivas.
Los prototipos de envío lo morderán más pronto y más duro de lo que jamás haya imaginado. Cógelo de mi.