Estoy trabajando para integrar las pruebas unitarias en el proceso de desarrollo en el equipo en el que trabajo y hay algunos escépticos. ¿Cuáles son algunas buenas maneras de convencer a los desarrolladores escépticos en el equipo del valor de las pruebas unitarias? En mi caso específico, estaríamos agregando pruebas unitarias a medida que agregamos funcionalidades o arreglamos errores. Desafortunadamente, nuestra base de código no se presta a pruebas fáciles.
Todos los días en nuestra oficina hay un intercambio que dice algo así:
"Hombre, me encantan las pruebas de unidad, he podido hacer un montón de cambios en la forma en que funciona algo y luego pude confirmar que no había roto nada al ejecutar la prueba otra vez ..."
Los detalles cambian diariamente, pero el sentimiento no. Las pruebas unitarias y el desarrollo dirigido por pruebas (TDD, por sus siglas en inglés) tienen tantos beneficios ocultos y personales, así como los beneficios obvios que no puedes explicar a alguien hasta que lo estén haciendo ellos mismos.
Pero, ignorando eso, ¡aquí está mi intento!
Pruebas unitarias le permite hacer grandes cambios en el código rápidamente. Sabes que funciona ahora porque ejecutaste las pruebas, cuando haces los cambios que necesitas hacer, necesitas que las pruebas vuelvan a funcionar. Esto ahorra horas.
TDD le ayuda a darse cuenta de cuándo detener la codificación. Sus pruebas le dan la confianza de que ya ha hecho lo suficiente y puede dejar de ajustar y pasar a la siguiente cosa.
Las pruebas y el código trabajan juntos para lograr un mejor código. Su código puede ser malo/buggy. Tu prueba podría ser mala/con errores. En TDD, usted está apostando a las posibilidades de que ambos sea malo/buggy sea bajo. A menudo es la prueba la que necesita corrección, pero sigue siendo un buen resultado.
TDD ayuda a codificar el estreñimiento. Cuando se enfrente a un trabajo grande y desalentador por delante, escribir las pruebas lo pondrá en movimiento rápidamente.
Las pruebas unitarias le ayudan a comprender realmente el diseño del código en el que está trabajando. En lugar de escribir código para hacer algo, está comenzando por delinear todas las condiciones a las que está sujeto el código y qué resultados esperaría de eso.
Las Pruebas Unitarias le brindan retroalimentación visual instantánea, a todos nos gusta la sensación de todas esas luces verdes cuando hemos terminado. Es muy satisfactorio. También es mucho más fácil continuar donde lo dejó después de una interrupción porque puede ver dónde llegó: la próxima luz roja que necesita ser reparada.
Contrariamente a la creencia popular, la prueba de unidad no significa escribir el doble de código, o codificar más despacio. Es más rápido y más robusto que la codificación sin pruebas una vez que lo dominas. El código de prueba en sí mismo suele ser relativamente trivial y no agrega una gran sobrecarga a lo que estás haciendo. Este es uno que solo creerás cuando lo hagas :)
Creo que fue Fowler quien dijo: "Las pruebas imperfectas, que se ejecutan con frecuencia, son mucho mejores que las pruebas perfectas que nunca se escriben". Interpreto que esto me da permiso para escribir pruebas en las que creo que serán más útiles incluso si el resto de la cobertura de mi código es lamentablemente incompleta.
Las buenas pruebas unitarias pueden ayudar a documentar y definir lo que se supone que debe hacer algo
Las pruebas unitarias ayudan con la reutilización del código. Migre su código y sus pruebas a su nuevo proyecto. Retoca el código hasta que las pruebas vuelvan a ejecutarse.
Mucho trabajo en el que estoy involucrado no hace bien la prueba de unidad (interacciones con el usuario de la aplicación web, etc.), pero aun así todos estamos infectados por la prueba en esta tienda, y más felices cuando tenemos nuestras pruebas atadas. No puedo recomendar el enfoque lo suficiente.
La prueba de unidad es muy parecida a ir al gimnasio. Sabes que es bueno para ti, todos los argumentos tienen sentido, así que empiezas a entrenar. Hay un Rush inicial, lo cual es genial, pero después de unos días empiezas a preguntarte si vale la pena. Te estás tomando una hora del día para cambiarte de ropa y correr en una rueda de hámster, y no estás seguro de que realmente estés ganando otra cosa que no sean las piernas y los brazos adoloridos.
Luego, después de tal vez una o dos semanas, justo cuando el dolor desaparece, una Gran Fecha límite comienza a acercarse. Necesitas pasar cada hora de vigilia tratando de hacer un trabajo "útil", así que eliminas cosas extrañas, como ir al gimnasio. Se quita el hábito, y para cuando se termina la Fecha límite grande, ya ha vuelto al punto de partida. Si logras volver al gimnasio, te sientes tan adolorido como la primera vez que fuiste.
Usted lee un poco, para ver si está haciendo algo mal. Comienzas a sentir un poco de rencor irracional hacia todas las personas felices y en forma que ensalzan las virtudes del ejercicio. Te das cuenta de que no tienes mucho en común. No tienen que conducir 15 minutos para ir al gimnasio; Hay uno en su edificio. No tienen que discutir con nadie sobre los beneficios del ejercicio; Es algo que todos hacen y aceptan como importante. Cuando se acerca un Big Deadline, no se les dice que el ejercicio es innecesario más de lo que su jefe le pedirá que deje de comer.
Entonces, para responder a tu pregunta, la prueba de unidad generalmente vale la pena, pero la cantidad de esfuerzo requerido no será la misma para todos. Las pruebas unitarias pueden requerir una enorme cantidad de esfuerzo si se trata de una base de código de espagueti en una empresa que no en realidad valora la calidad del código. (Muchos gerentes cantarán los elogios de Unit Testing, pero eso no significa que lo apoyen cuando sea importante).
Si está tratando de introducir la prueba de unidad en su trabajo y no ve toda la luz del sol y el arco iris que se le ha hecho esperar, no se culpe. Es posible que deba encontrar un nuevo trabajo para que realmente las Pruebas unitarias funcionen para usted.
La mejor manera de convencer ... encontrar un error, escribir una prueba de unidad para ello, solucionar el error.
Es poco probable que ese error en particular vuelva a aparecer, y puedes probarlo con tu prueba.
Si haces esto lo suficiente, otros se darán cuenta rápidamente.
thetalkingwalnut pregunta:
¿Cuáles son algunas buenas maneras de convencer a los desarrolladores escépticos en el equipo del valor de las pruebas unitarias?
Todo el mundo aquí va a acumular muchas razones inesperadas por las que la prueba de unidad es buena. Sin embargo, a menudo encuentro que la mejor manera de convencer a alguien de algo es escuchar a su argumento y abordarlo punto por punto. Si los escucha y los ayuda a expresar sus inquietudes verbales, puede abordar cada uno de ellos y quizás convertirlos a su punto de vista (o, al menos, dejarlos sin apoyo). ¿Quién sabe? Tal vez lo convencerán de que las pruebas unitarias no son apropiadas para su situación. No es probable, pero es posible. Quizás si publica sus argumentos en contra de las pruebas unitarias, podemos ayudar a identificar los contraargumentos.
Es importante escuchar y entender ambos lados del argumento. Si tratas de adoptar pruebas de unidad con demasiada celo sin tener en cuenta las preocupaciones de la gente, terminarás con una guerra religiosa (y probablemente pruebas de unidad realmente sin valor). Si lo adopta lentamente y comienza aplicándolo donde verá el mayor beneficio al menor costo, podría demostrar el valor de las pruebas unitarias y tener una mejor oportunidad de convencer a las personas. Me doy cuenta de que esto no es tan fácil como parece, por lo general requiere algo de tiempo y métricas cuidadosas para elaborar un argumento convincente.
Las pruebas unitarias son una herramienta, como cualquier otra, y deben aplicarse de tal manera que los beneficios (captura de errores) superen los costos (el esfuerzo por escribirlos). No los use si/donde no tienen sentido y recuerde que son solo parte de su arsenal de herramientas (por ejemplo, inspecciones, aserciones, analizadores de código, métodos formales, etc.). Lo que les digo a mis desarrolladores es esto:
Pueden omitir la escritura de una prueba para un método si tienen un buen argumento de por qué no es necesario (por ejemplo, demasiado simple para que valga la pena o demasiado difícil para que valga la pena) y cómo se verificará el método de otra manera (por ejemplo, inspección, afirmaciones , métodos formales, pruebas interactivas/de integración). Deben considerar que algunas verificaciones, como las inspecciones y las pruebas formales, se realizan en un momento determinado y luego deben repetirse cada vez que cambia el código de producción, mientras que las pruebas unitarias y las afirmaciones se pueden usar como pruebas de regresión (escritas una vez y ejecutadas varias veces después) ). A veces estoy de acuerdo con ellos, pero más a menudo debatiré si un método es realmente demasiado simple o difícil de probar por unidad.
Si un desarrollador argumenta que un método parece demasiado simple para fallar, ¿no vale la pena tomar los 60 segundos necesarios para redactar una prueba de unidad de 5 líneas para él? Estas 5 líneas de código se ejecutarán todas las noches (usted hace compilaciones nocturnas, ¿verdad?) Durante el próximo año o más y valdrá la pena el esfuerzo si solo una vez sucede para detectar un problema que puede haber tomado 15 minutos o más para identificarlo y depuración. Además, escribir las pruebas unitarias fáciles aumenta el número de pruebas unitarias, lo que hace que el desarrollador se vea bien.
Por otro lado, si un desarrollador argumenta que un método parece demasiado difícil de probar por unidad (no vale la pena el esfuerzo significativo requerido), tal vez sea una buena indicación de que el método necesita ser dividido o refactorizado para probar las partes fáciles. Generalmente, estos son métodos que dependen de recursos inusuales como singletons, la hora actual o recursos externos como un conjunto de resultados de base de datos. Por lo general, estos métodos deben ser refactorizados en un método que obtenga el recurso (por ejemplo, las llamadas getTime ()) y un método que tome el recurso como un argumento (por ejemplo, tome la marca de tiempo como un parámetro). Les dejé pasar por alto la prueba del método que recupera el recurso y en su lugar escriben una prueba de unidad para el método que ahora toma el recurso como un argumento. Por lo general, esto hace que escribir la prueba de la unidad sea mucho más simple y, por lo tanto, vale la pena escribir.
El desarrollador debe dibujar una "línea en la arena" en cuanto a lo exhaustivas que deben ser las pruebas unitarias. Más adelante en el desarrollo, cada vez que encontremos un error, deberían determinar si las pruebas unitarias más completas hubieran detectado el problema. Si es así y si dichos errores surgen repetidamente, deben mover la "línea" hacia la escritura de pruebas de unidad más completas en el futuro (comenzando con la adición o expansión de la prueba de unidad para el error actual). Necesitan encontrar el equilibrio adecuado.
Es importante darse cuenta de que las pruebas unitarias no son una bala de plata y hay es algo así como demasiadas pruebas unitarias. En mi lugar de trabajo, cada vez que aprendemos una lección, inevitablemente escucho "necesitamos escribir más pruebas de unidad". La gerencia asiente con la cabeza porque está maltratada porque "pruebas de unidad" == "bien".
Sin embargo, debemos entender el impacto de "más pruebas unitarias". Un desarrollador solo puede escribir ~ N líneas de código a la semana y usted necesita averiguar qué porcentaje de ese código debe ser un código de prueba de unidad frente a un código de producción. Un lugar de trabajo poco estricto puede tener el 10% del código como pruebas unitarias y el 90% del código como código de producción, dando como resultado un producto con muchas características (aunque muy defectuosas) (piense en MS Word). Por otro lado, una tienda estricta con un 90% de pruebas unitarias y un 10% de código de producción tendrá un producto sólido como una roca con muy pocas características (piense en "vi"). Es posible que nunca escuche informes sobre la caída de este último producto, pero es probable que tenga tanto que ver con que el producto no se venda tan bien como con la calidad del código.
Peor aún, quizás la única certeza en el desarrollo de software es que "el cambio es inevitable". Supongamos que la tienda estricta (90% de pruebas unitarias/10% del código de producción) crea un producto que tiene exactamente 2 funciones (suponiendo que el 5% del código de producción == 1 característica). Si el cliente aparece y cambia una de las funciones, el cambio elimina el 50% del código (45% de las pruebas unitarias y el 5% del código de producción). La tienda laxa (10% de pruebas unitarias/90% código de producción) tiene un producto con 18 características, ninguna de las cuales funciona muy bien. Su cliente renueva completamente los requisitos para 4 de sus características. Aunque el cambio es 4 veces más grande, solo se destruye la mitad de la base del código (~ 25% = ~ 4.4% de pruebas unitarias + 20% del código de producción).
Lo que quiero decir es que debe comunicar que comprende el equilibrio entre pruebas de unidades demasiado pequeñas y demasiadas, esencialmente que ha analizado ambos lados del problema. Si puede convencer a sus compañeros y/o a su manejo de eso, gana credibilidad y quizás tenga una mejor oportunidad de ganárselos.
He jugado con la unidad de pruebas varias veces, y todavía estoy convencido de que vale la pena el esfuerzo dada mi situación.
Desarrollo sitios web, donde gran parte de la lógica implica crear, recuperar o actualizar datos en la base de datos. Cuando traté de "burlarme" de la base de datos con fines de pruebas unitarias, se ha vuelto muy desordenado y parece un poco inútil.
Cuando escribí pruebas unitarias sobre la lógica de negocios, nunca me ayudó mucho a largo plazo. Como trabajo en gran parte solo en proyectos, tiendo a saber de forma intuitiva qué áreas del código pueden verse afectadas por algo en lo que estoy trabajando, y las pruebo manualmente. Quiero ofrecer una solución a mi cliente lo más rápido posible, y las pruebas unitarias a menudo parecen una pérdida de tiempo. Hago una lista de pruebas manuales y las recorro yo mismo, marcándolas mientras voy.
Puedo ver que puede ser beneficioso cuando un equipo de desarrolladores trabaja en un proyecto y actualiza el código de cada uno, pero incluso así creo que si los desarrolladores son de alta calidad, una buena comunicación y un código bien escrito deberían ser suficientes. .
Una gran cosa acerca de las pruebas unitarias es que sirven como documentación de cómo debe comportarse su código. Las buenas pruebas son como una implementación de referencia, y los compañeros de equipo pueden mirarlas para ver cómo integrar su código con el suyo.
La prueba de unidad bien vale la inversión inicial. Desde que empecé a usar la prueba de unidad hace un par de años, he encontrado algunos beneficios reales:
Los fragmentos de código pueden ser de gran ayuda para reducir la sobrecarga de crear pruebas. No es difícil crear fragmentos que permitan la creación de un esquema de clase y un dispositivo asociado de prueba de unidad en segundos.
¡Debes probar lo menos posible!
es decir, debes escribir solo pruebas de unidad suficientes para revelar la intención. Esto a menudo se pasa por alto. Las pruebas unitarias te cuestan. Si haces cambios y tienes que cambiar las pruebas serás menos ágil. Mantenga las pruebas unitarias cortas y dulces. Entonces tienen mucho valor.
Muy a menudo veo muchas pruebas que nunca se romperán, son grandes y torpes y no ofrecen mucho valor, simplemente terminan ralentizándolas.
No vi esto en ninguna de las otras respuestas, pero una cosa que noté es que podría depurar mucho más rápido . No necesita profundizar en su aplicación con la secuencia correcta de pasos para llegar al código que está arreglando, solo para encontrar que ha cometido un error booleano y necesita hacerlo todo de nuevo. Con una prueba de unidad, puedes ingresar directamente al código que estás depurando.
[Tengo un punto para hacer que no puedo ver arriba]
"Todas las pruebas de unidad, no necesariamente se dan cuenta, HECHO"
Piénsalo, escribes una función para analizar una cadena y eliminar nuevos caracteres de línea. Como desarrollador novato, puede ejecutar algunos casos desde la línea de comandos implementándolo en Main () o juntar un extremo visual con un botón, atar su función a un par de cuadros de texto y un botón y ver lo que pasa.
Eso es una prueba de unidad: básica y mal organizada, pero prueba el código para algunos casos.
Escribes algo más complejo. Lanza errores cuando se analizan algunos casos (pruebas de unidad) y se realiza una depuración en el código y el rastreo. Miras los valores a medida que avanzas y decides si son correctos o incorrectos. Esto es una prueba de unidad hasta cierto punto.
Las pruebas unitarias aquí realmente están tomando ese comportamiento, formalizándolo en un patrón estructurado y guardándolo para que pueda volver a ejecutar esas pruebas fácilmente. Si escribe un caso de prueba de unidad "adecuado" en lugar de realizar una prueba manual, lleva la misma cantidad de tiempo, o tal vez menos de lo que tiene experiencia, y lo tiene disponible para repetir una y otra vez
Durante años, he tratado de convencer a las personas de que necesitaban escribir una prueba de unidad para su código. Tanto si escribieron las pruebas primero (como en TDD) o después de codificar la funcionalidad, siempre traté de explicarles todos los beneficios de tener pruebas unitarias para el código. Casi nadie discrepaba conmigo. No puede estar en desacuerdo con algo que es obvio, y cualquier persona inteligente verá los beneficios de la prueba unitaria y el TDD.
El problema con las pruebas unitarias es que requiere un cambio de comportamiento, y es muy difícil cambiar el comportamiento de las personas. Con palabras, conseguirás que mucha gente esté de acuerdo contigo, pero no verás muchos cambios en la forma en que hacen las cosas.
Tienes que convencer a la gente haciendo. Su éxito personal atraerá más personas que todos los argumentos que pueda tener. Si ven que no solo están hablando de prueba de unidad o TDD, sino que están haciendo lo que predican y tienen éxito, la gente tratará de imitarlo.
También debe asumir un papel principal, ya que nadie escribe la prueba de la unidad correctamente desde la primera vez, por lo que es posible que deba asesorarlos sobre cómo hacerlo, mostrarles el camino y las herramientas disponibles. Ayúdelos mientras escriben sus primeras pruebas, revise las pruebas que escriben por sí mismos y muéstreles los trucos, modismos y patrones que ha aprendido a través de sus propias experiencias. Después de un tiempo, comenzarán a ver los beneficios por sí mismos y cambiarán su comportamiento para incorporar pruebas unitarias o TDD en su caja de herramientas.
Los cambios no sucederán durante la noche, pero con un poco de paciencia, puede lograr su objetivo.
Una parte importante del desarrollo basado en pruebas que a menudo se pasa por alto es la escritura de código verificable. Parece una especie de compromiso al principio, pero descubrirá que el código comprobable también es, en última instancia, modular, mantenible y legible. Si aún necesita ayuda para convencer a la gente esta es una presentación sencilla y agradable sobre las ventajas de las pruebas unitarias.
Si su base de código existente no se presta para pruebas de unidad, y ya está en producción, puede crear más problemas de los que resuelve al tratar de refactorizar todo su código para que sea comprobable por unidad.
Puede que sea mejor poner esfuerzos para mejorar sus pruebas de integración. Hay un montón de código que es más fácil de escribir sin una prueba de unidad, y si un control de calidad puede validar la funcionalidad contra un documento de requisitos, entonces ya está. Envíalo.
El ejemplo clásico de esto en mi mente es un SqlDataReader incrustado en una página ASPX vinculada a un GridView. El código está todo en el archivo ASPX. El SQL está en un procedimiento almacenado. ¿Qué prueba de unidad? Si la página hace lo que se supone que debe hacer, ¿debería realmente rediseñarla en varias capas para tener algo que automatizar?
Una de las mejores cosas de las pruebas unitarias es que su código será más fácil de probar a medida que lo haga. El código de existencia preexistente creado sin pruebas siempre es un desafío porque, dado que no fueron diseñados para ser probados por una unidad, no es raro que haya un alto nivel de acoplamiento entre clases, objetos difíciles de configurar dentro de su clase, como un correo electrónico Enviar referencia de servicio - y así sucesivamente. ¡Pero no dejes que esto te desanime! Verá que el diseño general de su código mejorará a medida que comience a escribir pruebas unitarias, y cuanto más realice la prueba, más confianza tendrá en realizar aún más cambios sin temor a romper su aplicación o presentar errores. .
Hay varias razones para hacer una prueba unitaria de su código, pero a medida que avanza el tiempo, descubrirá que el tiempo que ahorra en las pruebas es una de las mejores razones para hacerlo. En un sistema que acabo de entregar, insistí en hacer pruebas de unidad automatizadas a pesar de las afirmaciones de que pasaría mucho más tiempo haciendo las pruebas que probando el sistema manualmente. Con todas mis pruebas de unidad realizadas, ejecuto más de 400 casos de prueba en menos de 10 minutos, y cada vez que tuve que hacer un pequeño cambio en el código, todo lo que me llevó a estar seguro de que el código aún funcionaba sin errores fue diez minutos. ¿Te imaginas el tiempo que uno pasaría para ejecutar esos 400 casos de prueba a mano?
Cuando se trata de pruebas automáticas, ya sean pruebas de unidad o pruebas de aceptación, todos piensan que es un esfuerzo inútil codificar lo que puede hacer manualmente, y en ocasiones es cierto, si planea realizar las pruebas una sola vez. La mejor parte de las pruebas automatizadas es que puede ejecutarlas varias veces sin esfuerzo, y después de la segunda o tercera ejecución, el tiempo y el esfuerzo que ha desperdiciado ya están pagados.
Un último consejo sería no solo probar la unidad de su código, sino comenzar a hacer la prueba primero (vea TDD y BDD para más información)
Las pruebas unitarias también son especialmente útiles cuando se trata de refactorizar o reescribir una pieza de un código. Si tiene una buena cobertura de pruebas unitarias, puede refactorizar con confianza. Sin pruebas de unidad, a menudo es difícil asegurarse de que no rompió nada.
Estoy trabajando como ingeniero de mantenimiento de una base de código grande, horrible y mal documentada. Ojalá las personas que escribieron el código hayan escrito las pruebas unitarias para ello.
Cada vez que hago un cambio y actualizo el código de producción, tengo miedo de poder introducir un error por no haber considerado alguna condición.
Si escribieran la prueba, los cambios en la base del código serían más fáciles y rápidos (al mismo tiempo, la base del código estaría en un mejor estado).
Creo que las pruebas unitarias son muy útiles al escribir api o marcos que deben durar muchos años y que deben ser utilizados/modificados/evolucionados por personas distintas de los codificadores originales.
En resumen - sí. Valen cada onza de esfuerzo ... hasta cierto punto. Al final del día, las pruebas siguen siendo un código, y al igual que el crecimiento típico de un código, sus pruebas eventualmente tendrán que ser refactorizadas para que sean mantenibles y sostenibles. ¡Hay un montón de GOTCHAS! cuando se trata de pruebas unitarias, pero hombre, oh hombre, oh hombre, nada, y me refiero a que NADA permite que un desarrollador realice cambios con más confianza que un rico conjunto de pruebas unitarias.
Estoy trabajando en un proyecto en este momento ... es algo TDD, y tenemos la mayoría de nuestras reglas de negocios encapsuladas como pruebas ... tenemos alrededor de 500 o más pruebas de unidad en este momento. Esta iteración pasada tuve que renovar nuestra fuente de datos y cómo nuestra aplicación de escritorio se interconecta con esa fuente de datos. Tardé un par de días, todo el tiempo que seguí haciendo pruebas de unidad para ver lo que rompí y lo arreglé. Hacer un cambio; Construye y ejecuta tus pruebas; Arregla lo que rompiste. Lavar, enjuagar, repetir según sea necesario. Lo que tradicionalmente habría tomado días de control de calidad y un montón de estrés en el barco fue, en cambio, una experiencia corta y agradable.
Prepárese por adelantado, un poco de esfuerzo adicional, y se paga 10 veces más tarde cuando tiene que comenzar a jugar con las características y funciones principales.
Compré este libro, que es uno de los libros más referenciados en mi estante, y lo consulto a diario: enlace de texto
Ocasionalmente, yo o uno de mis compañeros de trabajo pasamos un par de horas llegando al fondo de un error poco claro y una vez que se encuentra la causa del error, el 90% del tiempo no se prueba la unidad. La prueba de la unidad no existe porque el dev está recortando esquinas para ahorrar tiempo, pero luego pierde esto y más depuración.
Tomar la pequeña cantidad de tiempo para escribir una prueba unitaria puede ahorrar horas de depuración futura.
Cuando dijiste, "nuestra base de código no se presta a pruebas fáciles" es el primer signo de un olor de código. Escribir pruebas unitarias significa que normalmente se escribe un código de manera diferente para que el código sea más comprobable. En mi opinión, esto es algo bueno, ya que lo que he visto a lo largo de los años al escribir el código para el que tuve que escribir las pruebas, me obligó a presentar un diseño mejor.
No lo sé. Muchos lugares no realizan pruebas unitarias, pero la calidad del código es buena. Microsoft hace la prueba de unidad, pero Bill Gates dio una pantalla azul en su presentación.
Pruebas unitarias definitivamente vale la pena el esfuerzo. Desafortunadamente, ha elegido un escenario difícil (pero desafortunadamente común) en el cual implementarlo.
El mejor beneficio de las pruebas de unidad que obtendrá es cuando lo usa desde cero: en algunos proyectos pequeños y seleccionados, he tenido la suerte de escribir mis pruebas de unidad antes de implementar mis clases (la interfaz ya estaba completa en este punto). punto). Con las pruebas de unidad adecuadas, encontrará y solucionará errores en sus clases mientras aún están en su infancia y no en ningún lugar cerca del complejo sistema en el que, sin duda, se integrarán en el futuro.
Si su software está sólidamente orientado a objetos, debería poder agregar pruebas de unidad a nivel de clase sin demasiado esfuerzo. Si no eres tan afortunado, deberías intentar incorporar las pruebas de unidad siempre que puedas. Asegúrese de que cuando agregue una nueva funcionalidad, las nuevas piezas estén bien definidas con interfaces claras y encontrará que las pruebas unitarias hacen su vida mucho más fácil.
Escribí un blog muy grande sobre el tema. Descubrí que las pruebas unitarias por sí solas no valen la pena y generalmente se cortan cuando se acercan los plazos.
En lugar de hablar de pruebas unitarias desde el punto de vista de verificación de "prueba después", deberíamos observar el verdadero valor encontrado cuando se dispuso a escribir una espec.
Esta simple idea ha cambiado la forma en que escribo el software y no volvería a la forma "antigua".
Una cosa que nadie ha mencionado aún es lograr que todos los desarrolladores se comprometan a ejecutar y actualizar cualquier prueba automatizada existente. Las pruebas automatizadas a las que se reincorpora y encuentran rotos debido al nuevo desarrollo pierden mucho valor y hacen que las pruebas automatizadas sean realmente dolorosas. La mayoría de esas pruebas no indicarán errores ya que el desarrollador ha probado el código manualmente, por lo que el tiempo dedicado a actualizarlos es simplemente un desperdicio.
Convencer a los escépticos de no destruir el trabajo que hacen los demás en las pruebas unitarias es mucho más importante para obtener valor de las pruebas y podría ser más fácil.
Pasar horas actualizando las pruebas que se han interrumpido debido a las nuevas funciones cada vez que se actualiza desde el repositorio no es productivo ni divertido.
Descubrí TDD hace un par de años, y desde entonces escribí todos mis proyectos favoritos usándolo. He estimado que toma aproximadamente el mismo tiempo para TDD un proyecto como lo requiere un vaquero juntos, pero tengo tanta confianza en el producto final que no puedo evitar una sensación de logro.
También siento que mejora mi estilo de diseño (mucho más orientado a la interfaz en caso de que necesite burlarme de las cosas) y, como escribe la publicación verde en la parte superior, ayuda a "codificar el estreñimiento": cuando no sabes qué. para escribir a continuación, o si tiene una tarea desalentadora frente a usted, puede escribir en pequeño.
Finalmente, me parece que, con mucho, la aplicación más útil de TDD está en la depuración, aunque solo sea porque ya ha desarrollado un marco de consulta con el que puede hacer que el proyecto produzca el error de forma repetible.
Sí, la prueba de unidad definitivamente vale la pena, pero debes saber que no es una bala de plata. La prueba de unidad es un trabajo y tendrá que trabajar para mantener la prueba actualizada y relevante a medida que cambia el código, pero el valor ofrecido vale la pena el esfuerzo que tiene que poner. La capacidad de refactorizar con impunidad es un gran beneficio, ya que siempre puede validar la funcionalidad ejecutando sus pruebas después de cualquier código de cambio. El truco es no obsesionarse demasiado con la unidad de trabajo que está probando o con los requisitos de prueba de andamios y cuando una prueba de unidad es realmente una prueba funcional, etc. La gente discutirá sobre esto durante horas Al final, la realidad es que cualquier prueba que hagas como código de escritura es mejor que no hacerlo. El otro axioma tiene que ver con la calidad y no con la cantidad. He visto bases de código con miles de pruebas que esencialmente no tienen sentido, ya que el resto no prueba nada útil ni nada específico del dominio, como las reglas comerciales, etc. del dominio en particular. También he visto bases de código con un 30% de cobertura de código, pero las pruebas fueron relevantes, significativas y realmente impresionantes, ya que probaron la funcionalidad central del código para el que se escribió y expresaron cómo se debe usar el código.
Uno de mis trucos favoritos al explorar nuevos marcos de trabajo o bases de código es escribir pruebas unitarias para 'hacerlo' y descubrir cómo funcionan las cosas. Es una excelente manera de aprender más sobre algo nuevo en lugar de leer un documento seco :)
Recientemente pasé por la misma experiencia en mi lugar de trabajo y descubrí que la mayoría de ellos conocía los beneficios teóricos, pero tenía que ser vendido específicamente para los beneficios para ellos, así que aquí estaban los puntos que usé (con éxito):
y el grande ...
Desde mi experiencia, las pruebas unitarias y las pruebas de integración son "DEBEN TENER" en entornos de software complejos.
Para convencer a los desarrolladores de su equipo de que escriban pruebas unitarias, puede considerar la posibilidad de integrar el análisis de regresión de pruebas unitarias en su entorno de desarrollo (por ejemplo, en su proceso de compilación diaria).
Una vez que los desarrolladores sepan que si una prueba de unidad falla, no tienen que dedicar tanto tiempo a la depuración de la misma para encontrar el problema, se les animará más a escribirlos.
Aquí hay una herramienta que proporciona dicha funcionalidad:
Si está utilizando NUnit, una demostración simple pero efectiva es ejecutar los propios paquetes de prueba de NUnit frente a ellos. Ver un conjunto de pruebas real que le da un código base a un entrenamiento vale más que mil palabras ...
Lo único que hay que tener en cuenta acerca de las pruebas unitarias es que es una comodidad para el desarrollador.
En contraste, las pruebas funcionales son para los usuarios: cada vez que agrega una prueba funcional, está probando algo que el usuario verá. Cuando agrega una prueba de unidad, solo está haciendo su vida más fácil como desarrollador. Es un poco de lujo a ese respecto.
Tenga en cuenta esta dicotomía cuando tenga que elegir entre escribir una unidad o una prueba funcional.
Estoy de acuerdo con el punto de vista opuesto a la mayoría aquí: Está bien no escribir pruebas unitarias Especialmente la programación pesada de prototipos (AI, por ejemplo) es difícil de combinar con las pruebas unitarias.
Las pruebas unitarias ayudan mucho en proyectos que son más grandes de lo que cualquier desarrollador puede tener en la cabeza. Le permiten ejecutar el conjunto de pruebas de la unidad antes de registrarse y descubrir si rompió algo. Esto reduce un lote en instancias de tener que sentarse y girar sus pulgares mientras espera que alguien más arregle un error que registró, o ir a la molestia de revertir su cambio para que pueda trabajar. . También es inmensamente valioso en la refactorización, por lo que puede estar seguro de que el código refactorizado pasa todas las pruebas que hizo el código original.
Con Unit Test Suite, se pueden realizar cambios en el código y dejar el resto de las características intactas. Es una gran ventaja. ¿Utiliza Sutie de prueba de unidad y conjunto de pruebas de regresión cuando termina de codificar una nueva función?.
El objetivo de las pruebas unitarias es facilitar las pruebas. Es automatizado "hacer prueba" y ya está. Si uno de los problemas que enfrenta es difícil de probar el código, esa es la mejor razón para usar la prueba de unidad.
Hoy mismo, tuve que cambiar una clase para la que se había escrito una prueba de unidad anteriormente.
La prueba en sí estaba bien escrita e incluía escenarios de prueba en los que ni siquiera había pensado.
Afortunadamente, todas las pruebas se aprobaron y mi cambio se verificó rápidamente y se puso en el entorno de prueba con confianza.
Cuando prueba el software manualmente, normalmente tiene un pequeño conjunto de pruebas/acciones que utiliza. Eventualmente, cambiará automáticamente sus datos o acciones de entrada para navegar por los problemas conocidos. Las pruebas unitarias deben estar allí para recordarle que las cosas no funcionan correctamente.
¡Recomiendo escribir pruebas antes del código, agregar nuevas pruebas/datos para desarrollar la funcionalidad del código principal!
Como estudiante de física, estoy muy motivado para en realidad probar que mi código funciona como se supone. Puede probar esto lógicamente, lo que aumenta la dificultad drásticamente a medida que la implementación se vuelve más compleja, o puede hacer una prueba empírica de la función (lo más cerca posible) mediante buenas pruebas.
Si no proporciona una prueba lógica de la función, tiene que probar. La única alternativa es decir "Creo que el código funciona ..."
@George Stocker "Desafortunadamente, nuestra base de código no se presta a pruebas fáciles". Todos están de acuerdo en que las pruebas unitarias tienen beneficios, pero parece que para este código de base los costos son altos. Si los costos son mayores que los beneficios, ¿por qué deberían estar entusiasmados? Escucha a tus compañeros de trabajo; quizás para ellos el dolor percibido de las pruebas unitarias es mayor que el valor percibido de las pruebas unitarias.
Específicamente, intente ganar valor lo más pronto posible, y no un valor "xUnit is green", sino el código limpio que los usuarios y mantenedores valoran. Tal vez tenga que exigir pruebas de unidad para una iteración y luego discutir si vale la pena o no.
Haga que las primeras cosas que pruebe no estén relacionadas con las pruebas unitarias. Trabajo principalmente en Perl, así que estos son ejemplos específicos de Perl, pero puedes adaptarte.
¿Cada módulo carga y compila correctamente? En Perl, esto es una cuestión de crear un Foo.t para cada Foo.pm en la base de código que hace:
use_ok( 'Foo' );
¿Toda la POD (documentación de Plain Ol) está formateada correctamente? Use Test :: Pod para validar la validez del formato de todos los POD en todos los archivos.
Puede que no pienses que estas son cosas grandes, y no lo son, pero puedo garantizarte que tendrás alguna pendiente. Cuando estas pruebas se ejecutan una vez por hora y detectan el compromiso prematuro de alguien, harás que la gente diga "Hey, eso es genial".
Uno de los beneficios de las pruebas unitarias es la previsibilidad.
Antes de las pruebas unitarias, podría haber predicho con gran precisión cuánto tiempo llevaría codificar algo, pero no cuánto tiempo necesitaría para depurarlo.
En estos días, ya que puedo planificar qué pruebas voy a escribir, sé cuánto tiempo tomará la codificación, y al final de la codificación, ¡el sistema ya está depurado! Esto trae previsibilidad al proceso de desarrollo, que elimina mucha presión pero aún así conserva toda la alegría.
Unit Testing es una de las metodologías más adoptadas para el código de alta calidad. Su contribución a un código más estable, independiente y documentado está bien comprobada. El código de prueba de unidad se considera y maneja como una parte integral de su repositorio, y como tal requiere desarrollo y mantenimiento. Sin embargo, los desarrolladores a menudo se encuentran con una situación en la que los recursos invertidos en pruebas unitarias no son tan fructíferos como uno podría esperar. En un mundo ideal, cada método que codifiquemos tendrá una serie de pruebas que cubrirán su código y validarán su corrección. Sin embargo, generalmente, debido a limitaciones de tiempo, omitimos algunas pruebas o escribimos pruebas de baja calidad. En tal realidad, teniendo en cuenta la cantidad de recursos invertidos en el desarrollo y mantenimiento de las pruebas unitarias, uno debe preguntarse, dado el tiempo disponible, ¿qué código merece la prueba más? Y a partir de las pruebas existentes, ¿qué pruebas realmente vale la pena mantenerlas y mantenerlas? Ver aquí
Las pruebas unitarias lo ayudan a lanzar software con menos errores y reducen los costos generales de desarrollo. Puede hacer clic en el enlace para obtener más información sobre los beneficios de las pruebas unitarias
¿A quién estás tratando de convencer? Ingenieros o gerente? Si está tratando de convencer a sus compañeros de ingeniero, creo que lo mejor que puede hacer es apelar a su deseo de crear un software de alta calidad. Hay numerosos estudios que demuestran que encuentra errores, y si les importa hacer un buen trabajo, eso debería ser suficiente para ellos.
Si está tratando de convencer a la gerencia, lo más probable es que tenga que hacer algún tipo de razonamiento de costo/beneficio que diga que el costo de los defectos que no se detectarán es mayor que el costo de escribir las pruebas. Asegúrese de incluir también los costos intagables, como la pérdida de la confianza del cliente, etc.
Esto es muy centrado en .Net, pero ¿alguien ha probado Pex ?
Fui extremadamente escéptico hasta que lo probé, y wow, qué rendimiento. Antes de que pensara "este concepto no me va a convencer hasta que entienda qué es realmente hacer para beneficiarme". Me costó una sola vez cambiar de opinión y decir: "No cuidado cómo sabes que existe el riesgo de una excepción fatal allí, pero hay es y ahora sé Tengo que lidiar con eso "
Quizás el único inconveniente de este comportamiento es que marcará todo y le dará un retraso de seis meses. Pero, si tenía una deuda de código, siempre tenía una deuda de código, simplemente no lo sabía. Decirle a un PM hay un potencial de doscientos mil puntos de falla cuando antes de que te enteraras de unas pocas docenas es una perspectiva desagradable, lo que significa que es vital que el concepto sea explicado primero.