¿Usas pruebas unitarias en el trabajo? ¿Qué beneficios obtienes de ellos? [cerrado]

18

Había planeado estudiar y aplicar pruebas unitarias a mi código, pero después de hablar con mis colegas, algunos de ellos me sugirieron que no es necesario y tiene muy pocos beneficios. También afirman que solo unas pocas compañías realmente hacen pruebas unitarias con software de producción.

Tengo curiosidad por saber cómo las personas han aplicado pruebas unitarias en el trabajo y qué beneficios obtienen al usarlas, por ejemplo, mejor calidad de código, menor tiempo de desarrollo a largo plazo, etc.

Anónimo
fuente
13
"También afirman que solo unas pocas empresas hacen pruebas unitarias con software de producción". Eso significa que solo unas pocas empresas producen software de alta calidad. ¿Con qué grupo te quieres alinear? ¿Cómo puede "solo unas pocas compañías" ser una declaración negativa? Solo unas pocas empresas son tremendamente rentables; ¿eso lo hace malo? Solo unas pocas empresas son lugares realmente encantadores para trabajar; ¿eso lo hace malo? Solo unas pocas empresas minimizan su creación de residuos; ¿eso lo hace malo? Su comentario de "solo unas pocas compañías" no tiene sentido.
S.Lott
2
También es probablemente incorrecto, anecdóticamente, todavía tengo que trabajar para o con una empresa que al menos no hizo algún nivel de prueba de unidad
jk.
1
Yo diría que un programador que piensa que las pruebas unitarias "tienen muy poco beneficio" no tiene experiencia, o simplemente no sabe cómo escribir pruebas unitarias efectivas.
Toby
¿Cuántas pruebas unitarias usan los desarrolladores de este sitio?
JeffO
1
@ S.Lott: sin sentido, sí, sin embargo, todavía se usa como argumento para no hacer una prueba unitaria por aquellos que no quieren hacerlos. No estoy defendiendo su punto de vista aquí, sino todo lo contrario. Sin embargo, esa declaración aún se hace y quienes lo hacen están convencidos de su valor y, dado que son ellos, debemos convencer de los beneficios reales de probar que descartarlo, ya que no tiene sentido, no ayudará mucho a la causa mayor.
Newtopian

Respuestas:

20

algunos me sugieren que no es necesario

Bueno, en sentido estricto tienen razón: las pruebas, las revisiones de código, el control de fuente, etc. tampoco son estrictamente necesarios . Solo que muy pocos desarrolladores razonables trabajan sin estos a largo plazo. La mayoría de nosotros hemos aprendido (a menudo de la manera más difícil, de nuestros propios errores) por qué estas son las mejores prácticas.

y tiene muy poco beneficio.

Esto no es cierto en la mayoría de los casos. Es decir, si hablamos de software de producción que se supone que está en uso, por lo tanto, en mantenimiento, en los próximos años.

También afirman que solo unas pocas empresas realizan pruebas unitarias con software de producción.

Esto puede ser cierto (aunque en mi experiencia cada vez menos), pero no tiene nada que decir sobre el valor de las pruebas unitarias. En contraste con esto, la vieja broma "La mierda es buena: ¡50 mil millones de moscas no pueden estar equivocadas!" ;-)

¿aplicó la prueba unitaria en su trabajo y qué obtiene de ella? (por ejemplo, mejor calidad de código, reducir el tiempo a largo plazo, etc.)

He estado aplicando pruebas unitarias en mi trabajo, siempre que fue posible, durante más de 10 años. Esa sensación de confianza en mi código, sabiendo que funciona, y puedo probarlo en cualquier momento, en cualquier lugar, en unos segundos, una y otra vez, en lugar de solo creer en él, no tiene precio. Me da el coraje de refactorizar mi código, mejorar su diseño o corregir errores, sin temor a romper la funcionalidad existente. Nunca volvería a esos viejos tiempos de "codificar y rezar".

Péter Török
fuente
14

Hago pruebas unitarias, pero no (o pocas) en el trabajo

Los principales beneficios de las pruebas que obtengo son que la refactorización es mucho más fácil y que se nota la regresión (es decir, la reintroducción de errores ya corregidos).

Probar vidas con 'la compilación': comprueba el software con pruebas en ejecución y no se registra hasta que todas las pruebas se estén ejecutando con su modificación.

Entonces, en mi experiencia, escribir pruebas es casi inútil cuando se hace de una manera de lobo solitario. Cuando siempre tiene que arreglar sus pruebas para acomodar los cambios que hicieron los demás, cuando los compañeros de trabajo pueden eliminar las pruebas (sucedió en mis trabajos anteriores) porque 'no me dejarán implementar', etc., solo son un trabajo adicional con Los beneficios se queman instantáneamente por el resto del equipo.

Cuando todo el equipo está de acuerdo (y, en un equipo de 1, eso es fácil), en mi experiencia, las pruebas son un gran beneficio para la calidad, el estilo y la solidez del Proyecto.

Pero en un equipo que honestamente cree que 'solo unas pocas compañías prueban su código automáticamente' y están convencidas de que de todos modos son una pérdida de tiempo, parece que hay pocas esperanzas de obtener los beneficios, pero existe una gran posibilidad de que se le haga responsable de la 'pérdida de tiempo' al señalar errores.

La mejor oportunidad para introducir pruebas sería un pequeño proyecto bajo su exclusiva responsabilidad. Allí tendría la oportunidad de brillar y demostrar el valor de las pruebas.

keppla
fuente
1
Perdón por sonar negativo, pero todavía estoy quemado por 'cómo hacer las cosas como un gruñido';)
keppla
Muy buen consejo. El problema es que cuando se hace bien, en realidad no se ve el beneficio de las pruebas unitarias. Solo puede ver el daño cuando no realiza pruebas unitarias. Entonces, si necesita convencer a otros con estadísticas, en lugar de teoría, está bastante jodido.
Peter Kruithof
12
@keppla, he estado escribiendo pruebas unitarias en proyectos donde mis compañeros de equipo ni siquiera han oído hablar de las pruebas unitarias antes. Una vez que mis pruebas lograron detectar algunos errores que de otro modo habrían pasado desapercibidos, los demás comenzaron a darse cuenta y pronto quisieron aprender ellos mismos. La evidencia concreta es el rey.
Péter Török
1
@keppla, bastante justo, si los compañeros de equipo están predispuestos al nivel de perder su sentido común, no hay forma de convencerlos con una prueba lógica :-( En tal caso, con un fuerte apoyo de la gerencia, aún podría tener éxito para impulsar la idea. , pero sin eso, no hay esperanza.
Péter Török
3
Con frecuencia 'rompes' las pruebas cambiando la interfaz, eliminando clases, etc. Cuando haces 'probar primero', no experimentas esto como 'romper', sino como el primer paso 'Rojo'. Pero cuando estás en la mentalidad "Solo agrega algunas líneas hasta que funcione", las pruebas son solo más líneas. Y cuando alguien "así" los "arregla", las pruebas tienden a degradarse en utilidad, hasta que realmente no sirven para nada. La profecía autocumplida 4tw!
keppla
7

Tiendo a estar del lado de tus colegas, pero solo hasta cierto punto.

El problema con las pruebas unitarias es que se escriben con frecuencia y sin pensar en casos triviales donde la investigación superficial del código revela que funcionará sin importar qué. Por ejemplo:

def add(x, y)
  x + y
end

Junto con una docena de pruebas para asegurarse de que la adición realmente funcione para casos de uso elegidos arbitrariamente. Duh ...

La premisa general detrás de las pruebas unitarias es: si su código no contiene errores, es porque no ha probado lo suficiente. Ahora, cuándo escribir pruebas unitarias adecuadas. Respuestas:

  1. Cuando estas probando
  2. Cuando estás depurando
  3. A medida que desarrollas cosas realmente difíciles

Repasemos cada uno, suponiendo que esté desarrollando algún tipo de aplicación web.

Escribe algo de código en la nueva funcionalidad, y ya debería funcionar razonablemente bien. Luego buscas tu navegador y verificas que funciona haciendo pruebas más intensas, ¿verdad? Bzzzt! ... Respuesta incorrecta. Escribes una prueba unitaria. Si no lo hace ahora, probablemente nunca lo hará. Y este es uno de los lugares donde las pruebas unitarias funcionan muy bien: para probar la funcionalidad de alto nivel.

Entonces descubres un error (¿quién nunca pierde ninguno?). Esto nos lleva al punto dos. Vuelve al código y comienza a seguir los pasos. Mientras lo hace, escriba las pruebas unitarias en los puntos clave de interrupción donde tener datos consistentes y correctos es crucial.

El último punto es al revés. Estás diseñando una funcionalidad complicada que implica un montón de metaprogramación. Rápidamente genera un árbol de decisión con miles de escenarios potenciales, y debe asegurarse de que todos y cada uno de ellos funcionen. Al escribir tales cosas, un cambio de aspecto simple aquí o allá puede tener consecuencias inimaginables más abajo en la cadena alimentaria. Supongamos que está diseñando una implementación MPTT utilizando disparadores SQL, para que pueda funcionar con declaraciones de varias filas.

En este tipo de entorno espinoso, generalmente querrás automatizar altamente tus pruebas. Entonces, escribe scripts para automatizar la generación de datos de prueba y ejecuta una gran cantidad de pruebas unitarias en estos datos de prueba. Una cosa crucial para no perder de vista al hacer esto, es que también necesita escribir pruebas unitarias para su generador de pruebas unitarias.

En pocas palabras: pruebas unitarias, definitivamente sí. Pero evite las funcionalidades básicas, hasta que realmente las necesite para la depuración o para asegurarse de que algunas funcionalidades meticulosas funcionen correctamente (incluidas, en este último caso, las pruebas mismas).

Denis de Bernardy
fuente
Como dijo Kent Beck: "prueba todo lo que pueda romperse".
Péter Török
1
Acordando de todo corazón con él. Mi principal esperanza es que el OP tome nota de: no olvide probar las pruebas cuando corresponda. :-)
Denis de Bernardy
7

Todo el código debe ser probado. No hay elección al respecto.

El código no probado es inútil: no se puede confiar para hacer nada.

Puede escribir pruebas unitarias o puede esperar escribir pruebas de integración de nivel superior o pruebas de aceptación.

Las pruebas unitarias son más fáciles de escribir, más fáciles de depurar y más fáciles de administrar.

Las pruebas de integración se basan en suposiciones de que las unidades realmente funcionan. Sin pruebas unitarias, ¿cómo sabes que funcionan las unidades? ¿Cómo puede depurar una prueba de integración si no sabe que las unidades individuales que se integran realmente funcionan?

Las pruebas de aceptación, de manera similar, dependen de todas las piezas y piezas en funcionamiento. ¿Cómo puede saber si las piezas funcionan sin tener un conjunto de pruebas unitarias?

La prueba es obligatoria. Todas las pruebas de nivel superior dependen de las unidades que realmente funcionan.

Eso hace que las pruebas unitarias sean una necesidad lógica. No hay otra opción.

S.Lott
fuente
1
No hay otra opción ... si te importa la calidad. La mayoría de las organizaciones de software no se preocupan realmente por la calidad (en la medida en que se niegan a enviar software que se sabe que está dañado).
Joeri Sebrechts
@Joeri Sebrechts: No es un problema de calidad. Es un problema de "ya está hecho". Incluso el software malo necesita ser probado para demostrar que hace algo, cualquier cosa. La lógica simple dicta que debe haber una prueba para demostrar que funciona. Incluso una mala prueba es una prueba. La lógica simple dicta que una prueba del todo debe incluir pruebas de las partes. La prueba unitaria simplemente es requerida por la lógica, nada más. No consideraciones de calidad, sino por definición de "hecho".
S.Lott
1
Usar el software es una prueba de sí mismo. Muchas organizaciones están felices de hacer que el usuario haga las pruebas. No digo que sea algo bueno, pero es así. De hecho, puede optar por no probar antes de la entrega, descargando las pruebas al usuario final. Puedes, pero no deberías.
Joeri Sebrechts
1
@Joeri Sebrechts: En realidad, no puedes. No puede entregar el software, al azar, a un usuario para pruebas de aceptación. Debe haber ejecutado el software al menos una vez para asegurarse de que parecía funcionar. Esa es una prueba, una mala prueba, pero una prueba. Lógicamente, esa mala prueba incorporó malas pruebas unitarias. Existieron, a pesar de que eran muy malos.
S.Lott
su definición de una prueba unitaria es inútil para esta discusión. Una prueba unitaria es una prueba codificada y no es necesario en absoluto para enviar software. (pero es bueno hacerlo en muchas circunstancias)
Martin Ba
6

Utilizo pruebas unitarias para todo lo que escribo, y no dejo que ningún código no probado pase la revisión sin un caso de prueba. (Pero me falta una herramienta de cobertura, así que tengo que razonar sobre la cobertura de la prueba. Una cosa a la vez ...)

Es bastante simple: si no puede demostrar que su código funciona (¿y qué mejor manera que una especificación ejecutable en forma de prueba?), Entonces no funciona .

Esto me da:

  • Tranquilidad: mi servidor CI me dice que toda mi base de código funciona.
  • La capacidad de mejorar mi código: puedo reestructurar mi código, refactorizarlo, sabiendo que después de la reestructuración no he roto nada.
Frank Shearar
fuente
2
Agregaría una advertencia muy importante a eso: las pruebas unitarias por sí solas no garantizarán que "toda su base de código funcione". Se asegurará de que todas las unidades de trabajo de código de forma aislada, pero todavía hay una gran posibilidad de que los errores de integración, errores en la presentación visual de los datos, etc.
Ryan Brunner
A menos que su entorno pase "si no puede demostrar que su código no funciona, entonces funciona". : p
Davy8
@ Ryan: Por supuesto, sus pruebas de integración deberían conducir todo el proyecto. La pregunta era sobre las pruebas unitarias, así que hablé sobre las pruebas unitarias, pero, por supuesto , debe demostrar la necesidad de un código mediante una prueba de integración fallida. Y, por supuesto, debe tener un servidor CI que implemente automáticamente su base de código y ejecute todas las pruebas
Frank Shearar
@ Davy8: ¿En qué caso tiene problemas más serios que "funcionan las pruebas unitarias?".
Frank Shearar 01 de
4

Las pruebas unitarias son una disciplina. Como no es necesario que el código funcione, a menudo se descarta.

Sin embargo, es un método probado que conduce a un código robusto y con menos errores. No creo que deba explicarte los beneficios, como ya mencionaste. Si observa algunos de los principales proyectos de código abierto, ya sean bibliotecas javascript, marcos de trabajo completos o aplicaciones de un solo propósito, todos utilizan pruebas unitarias.

Sospecho que sus colegas que recomiendan no usarlo no son programadores. Si lo son, digamos que no hay muchas personas a las que valoro más que a personas como Martin Fowler o Kent Beck ;).

Como la mayoría de las mejores prácticas, los beneficios son a largo plazo, debe invertir algo de tiempo en ello. Podría escribir un script largo de código de procedimiento, pero todos sabemos que desearía haberlo escrito en un estilo orientado a objetos cuando necesite refactorizarlo después de 2 años.

Lo mismo ocurre con las pruebas unitarias. Si escribe pruebas unitarias para partes críticas en su aplicación, puede asegurarse de que funcione como está previsto, todo el tiempo, incluso después de refactorizar el código. Tal vez codificas tan bien que nunca tienes un error de regresión. Pero si no lo hace, o si un nuevo programador se une a su equipo, debe asegurarse de que los errores del pasado no vuelvan a ocurrir. Creo que su jefe también estaría contento con eso, en lugar de tener que presentar un informe de error que pensó que se resolvió hace medio año.

Peter Kruithof
fuente
3

Las pruebas unitarias requieren un lenguaje amigable para pruebas unitarias, un diseño amigable para pruebas unitarias y un problema amigable para pruebas unitarias.

C ++, el diseño multiproceso y la GUI serán una pesadilla, y la cobertura del problema será terrible.

.NET, ensamblaje dll de un solo subproceso reutilizable, la lógica computacional pura será muy fácil.

Vale la pena, no puedo decirlo realmente.

¿Refactorizas mucho? ¿Ves "errores estúpidos" como "uno por uno" en tu código?

Hagas lo que hagas, no seas ese tipo que critica a los demás por "no tienes pruebas unitarias, por lo tanto apestas". Si las pruebas lo ayudan, hágalo, si no, no es como si fueran una bala de plata.

Descifrador
fuente
1
¿Por qué el diseño multiproceso sería una pesadilla? Diseñe para puntos de sincronización y pruebe allí.
Frank Shearar
1
Porque el tiempo depende de las fases lunares, el reloj de la CPU, la basura y casi cualquier cosa. En un check-in, la prueba puede fallar, si tienes suerte, en otros 1000 no lo hará.
Codificador
1
He escrito cosas multiproceso controladas por pruebas. Definitivamente es factible.
Frank Shearar
44
basura, puede realizar pruebas unitarias en cualquier idioma.
jk.
1
Es difícil escribir pruebas unitarias para interacciones GUI, pero es por eso que aislamos algo (nuestro código de motor) que no tiene que ver con la GUI. Nos ayudó a tomar una buena decisión de separar el motor de la GUI, además, las Pruebas de Unidad actúan como nuestra interfaz en lugar de la GUI, solicitando y brindando la información que normalmente necesitaríamos.
Chance
3

Yo quiero a, pero he tenido la mala suerte de trabajar casi en su totalidad a las empresas que simplemente no les importa acerca de la calidad, y se centran más en conjunto con tirar basura que tal vez un poco sorta obras-si-te-estrabismo. He mencionado pruebas unitarias y me sale un "¿Eh?" tipo de aspecto (el mismo aspecto que obtengo cuando menciono los principios SOLID u ORM, o patrones de diseño más allá de "clase con todos los métodos estáticos", o siguiendo las convenciones de nomenclatura de .NET). Solo he estado en una compañía que entendió esas cosas, y desafortunadamente fue un contrato a corto plazo y el departamento se recortó para reducir costos, por lo que no hubo tiempo suficiente para aprender realmente.

He incursionado en pruebas unitarias en proyectos ficticios descartables, pero realmente no he entendido bien el TDD / BDD completo, y no tener un mentor que pueda ayudarlo hace que sea mucho más difícil hacerlo correctamente.

Wayne Molina
fuente
2

Nosotros los usamos. Un gran beneficio que obtenemos es que nuestro marco de pruebas unitarias verifica fugas de memoria y fallas de asignación . A veces, el problema está en el código de prueba de la unidad, pero a menudo está en el código de producción.

Es una excelente manera de encontrar esas cosas que se perderán en una revisión de código.

Las pruebas unitarias (deberían) también se ejecutan muy rápidamente y pueden ejecutarse como parte de su integración continua después de cada confirmación, y también por los desarrolladores antes de confirmar. Tenemos más de 1,000 que demoran menos de 20 segundos en ejecutarse.

Compare con más de 40 minutos para pruebas de automatización a nivel de sistema y horas / días para pruebas manuales. Por supuesto, las pruebas unitarias no son las únicas pruebas que debe hacer, pero a un nivel de código detallado pueden ayudar a encontrar errores y probar esos casos extremos que las pruebas de sistema / integración no pueden tocar. Nuestro código debe ser probado con más del 75% de cobertura de decisión y con un 100% de cobertura funcional, lo cual sería muy difícil de lograr sin pruebas unitarias.

Hugo
fuente
2

Diría que las pruebas unitarias agregan valor, pero no soy un gran discípulo de TDD. Encuentro el mayor beneficio con las pruebas unitarias cuando hago motores calc, o cualquier tipo de motor realmente y luego las clases de utilidad, las pruebas unitarias son muy útiles.

Prefiero las pruebas de integración automatizadas para los bloques más dependientes de los datos, pero todo depende, estoy en el negocio de los datos, por lo que muchos errores están más relacionados con los datos en nuestro entorno que cualquier otra cosa, y para eso las pruebas de integración automatizadas funcionan bien. Verificando los datos antes y después y generando informes de excepción de esas pruebas.

Por lo tanto, las pruebas unitarias realmente agregan valor, especialmente si la unidad que está probando puede recibir todas las entradas que necesita y trabajar por sí sola con la entrada dada. Nuevamente, en mi caso, los motores calc y las clases de utilidad son ejemplos perfectos de estos.

Marthinus
fuente
2

Costos: más lento para codificar, curva de aprendizaje, inercia del desarrollador

Beneficios: generalmente me encontré escribiendo un código mejor cuando probé por primera vez, SOLID sabia ...

Pero en mi humilde opinión, creo que el mayor beneficio es la confiabilidad en sistemas más grandes que cambian con frecuencia. Una buena prueba unitaria le ahorrará el trasero (hizo el mío) cuando lance múltiples versiones y pueda eliminar una gran parte de los costos asociados con los procesos manuales de control de calidad. Por supuesto, no garantizará un código libre de errores, pero detectará algunos difíciles de predecir. En sistemas complejos grandes, esto puede ser un gran beneficio.

Bob_Mac
fuente
0

Realizo algunas pruebas unitarias en el trabajo cuando tengo la oportunidad, y trato de convencer a mis colegas para que hagan lo mismo.

No soy religioso al respecto, pero la experiencia muestra que la utilidad y los métodos comerciales que han sido testículos unitarios son muy robustos y tienden a mostrar pocos o ningún error durante la fase de prueba, lo que al final reduce los costos del proyecto.

Philippe
fuente
0

Donde vi la verdadera ventaja de codificar las Pruebas unitarias y hacer que la ejecución de las pruebas unitarias formara parte del proceso de construcción diario fue en un proyecto con más de 30 desarrolladores trabajando en 3 continentes diferentes. Cuando las pruebas unitarias realmente brillaron fue cuando alguien cambiaba sutilmente una clase que mantenían sin comprender cómo las personas usaban esa clase. En lugar de esperar a que el código llegue al grupo de prueba, hubo comentarios inmediatos cuando las pruebas unitarias de otras personas comenzaron a fallar como resultado del cambio. [Es por eso que todas las pruebas unitarias deben ejecutarse rutinariamente, no solo las que escribió para su código].

Mis pautas para las pruebas unitarias son:

  1. Pruebe todas las condiciones que pueda imaginar para su código, incluidas entradas incorrectas, límites, etc.
  2. Todas las pruebas unitarias para todos los módulos deben ejecutarse regularmente (es decir, como parte de las compilaciones nocturnas)
  3. ¡Compruebe los resultados de la prueba de la unidad!
  4. Si alguien encuentra un error en su código que superó sus pruebas, ¡escriba una nueva prueba para ello!
jwernerny
fuente
0

Recientemente he aprendido TDD y encuentro que es muy útil. Da más confianza de que mi código se está comportando como esperaba. Junto con hacer cualquier refactorización que deseo hacer más fácil. Siempre que se encuentre un error, puede asegurarse de que a través de las pruebas no vuelva a aparecer.

La parte más difícil es escribir buenas pruebas unitarias.

Es un buen punto de referencia para su código.

Schleis
fuente