¿Qué tan grande debe ser mi proyecto para que yo pueda probarlo? [cerrado]

86

Supongo que mi proyecto está lo suficientemente desacoplado como para permitir pruebas unitarias. Pero, ¿qué tan grande, exactamente, en términos de clases y funciones tiene que ser mi proyecto para que las pruebas unitarias valgan la pena?

Todos cometemos errores y nadie es perfecto, pero me considero un programador decente para manejar los errores de pequeños proyectos al pasar. ¿O la unidad de prueba es una gran necesidad sin importar el tamaño de su proyecto?

Lamin Sanneh
fuente
26
La gran suposición incorrecta que está haciendo es que el proyecto es solo para usted y que es solo por ahora . ¿Qué pasa si lo dejas unos meses, haces otra cosa y luego vuelves a hacerlo? ¿Tendrá la misma confianza en ser un "programador decente" (que no tiene nada que ver con la posibilidad de probar o no)? ¿Qué pasa si alguien más se hace cargo de su proyecto ...? Un gran blogger (lamentablemente ya no está activo) escribió que siempre debe "atender al lector de código, no al escritor de código".
Amos M. Carpenter
66
¿Qué tal esto (para C # .NET): int x = 3 * (1/3); ¿Cuál es el valor almacenado en x después de que se completa la operación? Mi punto es que incluso el código de una línea puede requerir pruebas porque podría provocar un error, ya sea porque no lo sabe o porque lo sabe pero hizo el código incorrecto.
NoChance
2
@aaamos, creo que te estás perdiendo mi punto. El hecho de que solo se me haga esta pregunta muestra que también considero atender al lector de código.
Lamin Sanneh
13
Después de haberlo hecho en ambos sentidos, puedo decirle que es mucho más fácil escribir las pruebas a medida que avanza (es decir, mientras el proyecto es pequeño) que regresar y escribir pruebas unitarias más tarde cuando sienta que el proyecto se ha encontrado con algo arbitrario " deberíamos escribir pruebas ahora "condición.
Wonko the Sane
1
Estás haciendo la pregunta equivocada. No importa cuán grande sea el proyecto. La pregunta es, ¿cuánto te importa si es correcto? Si la corrección es importante, entonces las pruebas unitarias son una forma efectiva de mejorar la corrección.
Mark E. Haase

Respuestas:

206

Tu proyecto ya es lo suficientemente grande.

En mi experiencia, una clase y una función han sido suficientes para considerar la necesidad de pruebas unitarias.

    class Simple {
        boolean reallySimple() {
            return true; // how do we make sure it doesn't change to false?
        }
    }


    class SimpleTest {
        void assertReallySimple() {
            // ensure reallySimple return value isn't changed unexpectedly
            UnitTestFramework.assertTrue(new Simple().reallySimple());
        }
    }
mosquito
fuente
24
Seguramente deberías comenzar antes, en el punto de función 0 clase / 0 ... si estás siguiendo TDD :)
Kaz Dragon
115
+1. Si su programa es lo suficientemente grande como para tener errores, es lo suficientemente grande como para tener pruebas unitarias.
Jason Orendorff
99
@JasonOrendorff: Me estoy burlando de eso en un póster y lo pongo en mi oficina. Brillante.
Justin ᚅᚔᚈᚄᚒᚔ
Además, permite una refactorización "segura".
Timo
77
Si bien no estoy necesariamente en desacuerdo con el sentimiento, si su código es realmente tan simple, probablemente podría salirse con la suya con solo afirmaciones en lugar de pruebas unitarias completas.
Chuu
109

Nunca me he metido en la idea de "debes probar la unidad todo", aunque ciertamente hay personas que sí lo tienen (¡mira la respuesta del mosquito !).

En lo que a mí respecta, los principales beneficios de las pruebas unitarias son:

  1. Ayudando a garantizar que los cambios no rompan las cosas.
  2. Ayudándole a diseñar interfaces sensatas para sus clases (ya que lo obliga a ser un cliente para su propio código).
  3. Ayuda a documentar cómo se espera que se use su código.

Básicamente, debe sopesar el tiempo que le llevará escribir y mantener pruebas contra estos factores.

El número 1 suele ser suficiente para que valga la pena escribir pruebas. En mi experiencia,> 95% del código se modifica tarde o temprano.

vaughandroid
fuente
8
Esté de acuerdo con esto: cuando trabaje en una sola tienda de desarrolladores, debe lograr un equilibrio entre la calidad del software y probar todo (lo que puede tomar mucho tiempo). No olvide que cada vez que realice un cambio, es posible que deba modificar las pruebas de su unidad para adaptarlas
Matt Wilko
1
No debe probar todo, pero debe probar cualquier comportamiento que esté expuesto al mundo exterior. Ciertamente, hay / hay costos de mantenimiento para las pruebas, y como dijo Kent Beck en alguna respuesta SO (creo que fue SO), pruebe lo suficiente como para asegurarse de que su código es correcto.
Wayne Werner
10
Agregaría que si solo está realizando pruebas automáticas mínimas, las pruebas unitarias son el nivel incorrecto para apuntar. En su lugar, realice pruebas de integración / humo de alto nivel que empujen algunos conjuntos de datos a través de su aplicación de extremo a extremo sin burlarse de nada. Desea que estas pruebas ejerzan la mayor cantidad posible de su base de código y cubran todos los casos de uso normales y las rutas de ejecución. Una probabilidad del 75% de saber que sus cambios rompieron algo, en algún lugar de la aplicación, es más beneficiosa que una probabilidad del 5% de saber que rompió SomeClass.OneOfTheHandfulOfTestedFunctions ().
Dan Neely
3
Uh, creo que te perdiste uno: "¡Asegurarte de que el código funcione de la forma en que se supone que debe hacerlo!"
BlueRaja - Danny Pflughoeft
3
@ BlueRaja-DannyPflughoeft: En realidad, sería más exacto decir: "¡Asegurarse de que el código pase las pruebas unitarias que ha escrito!"
vaughandroid
34

Es simple: no necesita pruebas unitarias si descartará el programa después de ejecutarlo una vez.

Si esto le parece excesivo, considere lo que significaría la alternativa. Si hubiera algún tamaño por debajo del cual las pruebas unitarias no pagan, tendría que seguir juzgando en su mente: "¿Ya he alcanzado el tamaño mágico? ¿Debería comenzar a escribir pruebas?" Ahora, los programadores son notoriamente malos para predecir el futuro, y son notoriamente malos para juzgar su propia habilidad. El código que ahora te parece claro como el cristal se volverá incomprensible, incluso para ti, incluso esperando un mes. Un proyecto en el que esté absolutamente seguro nunca se volverá a utilizar, y que se mantiene solo con la remota posibilidad de que desee ver cómo resolvió algo antes, se le solicitará nuevamente y recibirá solicitudes de cambio.

Por lo tanto, es muy probable que juzgue mal si las pruebas son útiles o no, y cuando comience a necesitar pruebas, ya no está 100% seguro de cuáles son realmente las semánticas exactas para probar. Como creo que todos, excepto los programas triviales únicos, se benefician de las pruebas unitarias, considero que el costo de gastar el esfuerzo en pruebas que nunca se vuelven a ejecutar es insignificante frente a los riesgos de extender el código no probado y mal entendido.

Kilian Foth
fuente
22
Los programadores son notoriamente malos al juzgar su propia habilidad de predecir el futuro
superM
3
@superM Estoy de acuerdo contigo. El programa "correr una vez y tirar" que ya escribí durante mi corta carrera se quedó, se ejecutó cada pocos días y se convirtió en un negocio crítico. Yo lo llamo el "temporarmanent", también conocido como el efecto temporal-permanente ... suspiro
Jalayn
@Jalayn ¿No es la respuesta simplemente que uno debería regresar y agregar pruebas unitarias tan pronto como esta realización llegue?
Cornel Masson
@CornelMasson Tiene toda la razón, espere que a menudo sea difícil convencer a los gerentes de que "aún no está terminado" porque faltan pruebas :-)
Jalayn
@Jalayn: ¡Demasiado cierto!
Cornel Masson
22

Hace algún tiempo encontré una buena publicación: ¿Por qué las pruebas unitarias aceleran el desarrollo ? Puede ayudarte a responder la pregunta.

... ¿Qué pasa si la base de código ... se proporcionó con un conjunto sustancial de pruebas unitarias? Un conjunto que diría: "si todas las pruebas tienen éxito, garantizo que el código sigue haciendo lo que debería hacer" y si una prueba falla, muestra exactamente dónde se rompe algún comportamiento. Esto es genial, podría cambiar el código para agregar cosas que quiero sin dudar si el código sigue haciendo lo que debería hacer, solo ejecuto las ... pruebas y tengo fe. Este es un gran mundo para estar como ingeniero de software. Me di cuenta de que podía avanzar mucho más rápido ...

Tengo fe".

Esta es probablemente la razón más importante por la que las pruebas unitarias aceleran el desarrollo en un contexto empresarial.

Puedo confiar en que todo sigue funcionando si pasan todas las pruebas. Si las pruebas fallan, señalarán exactamente dónde está el problema ...

... debe tener una alta cobertura de prueba unitaria y buenas pruebas unitarias . Cuando se respetan estas condiciones, se encontrará en una situación en la que el esfuerzo para agregar nuevas funcionalidades es casi independiente del tamaño de la aplicación y que a la larga acelerará el desarrollo .

Michael Feathers introdujo en uno de sus libros dos formas de trabajar con cambios en el código:

  • editar y rezar,
  • cubrir y modificar.

No importa qué tan grande sea la base del código.

Marcin Sanecki
fuente
18

Según Kent Beck en su respuesta a la pregunta de desbordamiento de pila ¿ Qué tan profundas son las pruebas de su unidad? , debe probar el código que tiende a equivocarse.

Si normalmente no cometo un tipo de error (como establecer las variables incorrectas en un constructor), no lo pruebo.

Mansuro
fuente
44
Buen punto, y esto implica que la pregunta del OP es incorrecta; si probar no tiene nada que ver con el tamaño del proyecto. Una base de código de 5 líneas puede necesitar pruebas, y un método de 1 línea en una base de código grande no (aunque otras cosas en esa base de código sí lo hacen).
Nathan Long
Esto puede funcionar para pequeños proyectos en los que está trabajando solo, pero para un proyecto que se realiza por trabajo (donde no controla quién trabajará en él en el futuro) o cualquier cosa que pueda ser de código abierto, necesita para probar todo Y debe comenzar de inmediato porque más tarde será "demasiado difícil rellenar todo el código que ya está escrito"
xaxxon
@xaxxon: Kent en realidad habla de eso en la misma respuesta a la que Mansuro se unió, diciendo: "Al codificar en un equipo, modifico mi estrategia para probar cuidadosamente el código que, colectivamente, tendemos a equivocarnos".
Henko
No, eso sigue siendo increíblemente miope. No puede saber quién trabajará en el código en el futuro. Este es el tipo de mentalidad que afecta a los desarrolladores junior.
xaxxon
5

Las pruebas unitarias se implementan para ahorrar tiempo y mejorar:

  • seguimiento de errores
  • refactorización y / o reescritura de código
  • pruebas de integración
  • pruebas de regresión, etc.

Es imprescindible escribir pruebas unitarias para partes relativamente complejas del programa.

Si está seguro de que escribir pruebas unitarias ahora no le ahorrará tiempo en el futuro, puede omitirlo. Sin embargo, nunca se sabe, y personalmente no puedo pensar en un caso en que sea más barato (en el sentido del tiempo, el dinero y los nervios) no escribir pruebas unitarias, sino hacer todas las pruebas manualmente.

superM
fuente
Generalmente una buena respuesta, entonces +1. Sin embargo, ¡creo que su punto final pierde el hecho de que aún querrá / necesitará probar manualmente sus pruebas unitarias!
vaughandroid
@Baqueta, tal vez no me pareció claro, pero no quise decir que las pruebas unitarias reemplacen por completo las pruebas manuales
superM
4

"¿Debo hacer una prueba unitaria de esto" generalmente puede responderse respondiendo la siguiente pregunta: "¿Es importante que esta función funcione correctamente y es importante para mí saber cuándo deja de funcionar?"

Por supuesto, es mucho más complicado que eso, pero esa es una buena manera de comenzar. Eventualmente, también pesará si el código ya se está probando en virtud de ser utilizado en otra función, o si su tiempo se gastaría mejor en otra función, etc.

Bryan Oakley
fuente
4

A menos que vaya a escribir código sin probarlo, siempre incurrirá en el costo de la prueba.

La diferencia entre tener pruebas unitarias y no tenerlas es la diferencia entre el costo de escribir la prueba y el costo de ejecutarla en comparación con el costo de la prueba a mano.

Si el costo de escribir una prueba unitaria es de 2 minutos y el costo de ejecutar la prueba unitaria es prácticamente 0, pero el costo de probar manualmente el código es de 1 minuto, entonces se equilibra cuando ha ejecutado la prueba dos veces.


Durante muchos años tuve la idea errónea de que no tenía tiempo suficiente para escribir pruebas unitarias para mi código. Cuando escribí las pruebas, estaban hinchadas, cosas pesadas que solo me animaron a pensar que solo debería escribir pruebas unitarias cuando sabía que eran necesarias.

Recientemente me animaron a usar Test Driven Development y descubrí que es una revelación completa. Ahora estoy firmemente convencido de que no tengo tiempo para no escribir pruebas unitarias .

En mi experiencia, al desarrollar teniendo en cuenta las pruebas, termina con interfaces más limpias, clases y módulos más enfocados y, en general , un código más SÓLIDO y comprobable.

Cada vez que trabajo con código heredado que no tiene pruebas unitarias y tengo que probar algo manualmente, sigo pensando "esto sería mucho más rápido si este código ya tuviera pruebas unitarias". Cada vez que tengo que probar y agregar funcionalidad de prueba unitaria al código con alto acoplamiento, sigo pensando "esto sería mucho más fácil si se hubiera escrito de forma desacoplada".


TL; versión DR :

Escriba una prueba cuando el costo de escribir la prueba, más el costo de ejecutarla tantas veces como sea necesario, sea menor que el costo de probarla manualmente tantas veces como sea necesario.

Sin embargo, recuerde que si usa TDD, es probable que el costo de escribir pruebas disminuya a medida que mejore, y a menos que el código sea absolutamente trivial, probablemente terminará ejecutando sus pruebas con más frecuencia de lo que espera.

Mark Booth
fuente
3

Pruebe tan pronto como observe que ocurren regresiones o tenga miedo de causar algunas con sus ediciones y no darse cuenta.

Enciende ese miedo, déjalo crecer a un tamaño adecuado: cuanto antes lo pruebes, mejor.

Tenga en cuenta que, dependiendo de su rol en el proyecto, las pruebas unitarias pueden no ser el único tipo de pruebas que desea escribir.

Todos están legítimamente obsesionados con las pruebas unitarias , debido a las malas prácticas de prueba convencionales en el pasado; pero si nunca ha probado antes, realmente debería centrarse en las pruebas en general , las pruebas unitarias por sí solas no resolverán los problemas del mundo.

ZJR
fuente
1
Veo que apuntas pero no prueba la unidad el punto de partida básico para los programadores de inicio. Y también podría elaborar más sobre lo que quiere decir con "prueba en general". Gracias.
Lamin Sanneh
1
Existen al menos otros dos tipos de pruebas: prueba de integración y pruebas de aceptación. Las pruebas unitarias cubren una unidad específica (por ejemplo, se supone que esta función de esta clase es Frab the Fizz). Usted se burla de todos los otros lugares donde esa clase interactúa, pasándole los datos falsos. Cuando haces pruebas de integración, combinas dos (o más) clases para asegurarte de que tus clases van juntas como crees que deberían. Eventualmente, construye suficientes pruebas para realizar pruebas de extremo a extremo de todo su sistema, a veces conocidas como "pruebas de humo".
Wayne Werner
También hay pruebas de regresión tout court. Las pruebas de regresión generalmente son más grandes que las pruebas unitarias, pueden demorar un día en construirse, pueden implicar el acceso a datos de prueba y entornos de prueba especiales. En realidad, las pruebas unitarias son una versión más pequeña, elegante y más fácil de mantener de las pruebas de regresión (a la antigua).
ZJR
1

Creo que no es el tamaño del proyecto sino el tipo de proyecto el que decide si debe usar pruebas o no.

Si está trabajando en una prueba de concepto, o en algún otro proyecto donde el objetivo es aprender de la codificación, entonces no se requieren pruebas. Si el proyecto está destinado a ser utilizado, tal vez incluso enviado a producción, entonces debe ser probado.

Una cita del "Código limpio" de Robert C. Martin : "Si es trivial escribir, es trivial probar", por lo que no hay excusa para saltear las pruebas de programas cortos y triviales.

Eivind Eidheim Elseth
fuente
0

Realmente no es una cuestión de tamaño, es lo que haces con él (y qué edad tiene). Si estoy aprendiendo cómo funciona una tecnología y planeo tirar la cosa (llamamos a esto un pico en Scrum), simplemente codificaré sin hacer muchas pruebas. Si está planeando desarrollarlo aún más (incluso si solo está bromeando), debe escribir pruebas alrededor del código. TDD es una técnica de diseño incluso antes de ser una técnica de prueba. Desea tener una idea clara de lo que quiere que haga el código antes de enredarse en los detalles de la ejecución. También me NORecomendamos intentar escribir extensas pruebas unitarias en torno a grandes cantidades de código heredado. Intente identificar aquellas partes que son complejas (tienen una alta complejidad ciclomática / sensación de código de espagueti) y aquellas partes que fallan con frecuencia (a menudo serán las mismas). Como otros han sugerido, iría a leer el libro de Kent Beck en TDD y definitivamente leería el libro de Michael Feather. Lo que no cubren mucho es el aspecto político de escribir pruebas unitarias en torno al código. Muchos desarrolladores odian tener que modificar su código para que sea comprobable, y muchos desarrolladores no sienten la necesidad de probar el código en absoluto. Es algo en lo que tenemos que trabajar como profesión. Se requiere que cualquier otra disciplina de ingeniería demuestre (a menudo matemáticamente) que su trabajo cumple con la especificación. Nosotros deberíamos hacer lo mismo.

John Dahle
fuente
-1

Enlazar proyectos en límites de clases o funcionalidades y luego juzgar si esto es adecuado para pruebas unitarias puede ser incorrecto. Existen numerosos beneficios de la prueba unitaria de una aplicación, pero la verdadera belleza comienza cuando tiene que mantener una aplicación o trabajar en un entorno distribuido. Entonces la elección viene aquí. Incluso un pequeño cambio en su código puede causar desastres.
No solo sugeriría 'Prueba de unidad' sino que también recomendaría verificar la cobertura de su código, asegurando que el máximo de su código esté cubierto con Prueba de unidad. El umbral para la cobertura del código no debe ser inferior al 95% y el objetivo debe estar alrededor del 100% . Puede buscar herramientas para rastrear la cobertura de su código y generar un informe.
Visual Studio proporciona datos de cobertura -http://msdn.microsoft.com/en-us/library/ms182496(v=vs.80).aspx
También puede usar NCover o dotCover.

Niks
fuente