Estoy tratando de defender las pruebas unitarias en mi grupo de trabajo, pero una objeción que a menudo recibo es que debe usarse solo para API exportadas externamente (que es solo una parte mínima y no crítica de nuestro sistema), y no en interna y privada código (que ahora solo tiene pruebas funcionales).
Si bien creo que esa prueba unitaria puede y debe aplicarse a todo el código, ¿cómo puedo persuadir a mis compañeros de trabajo?
unit-testing
Wizard79
fuente
fuente
Respuestas:
Sus compañeros de trabajo pueden estar confundiendo verdaderas pruebas unitarias con pruebas de integración. Si su producto es (o tiene) una API, las pruebas de integración se pueden programar como casos de prueba NUnit. Algunas personas creen erróneamente que esas son pruebas unitarias.
Puede intentar convencer a sus compañeros de trabajo con lo siguiente (estoy seguro de que ya sabe esto, todo lo que digo es que señalarlo a sus compañeros de trabajo podría ayudar):
fuente
Las razones para usar pruebas unitarias en código interno / privado son exactamente las mismas que para las API con soporte externo:
fuente
Si te refieres a privado de la manera en que creo que lo dices en serio, entonces no, no deberías probarlo unitario. Solo debe realizar pruebas unitarias de comportamiento / estado observable. Puede estar perdiendo el punto detrás del ciclo "rojo-verde-refactor" de TDD (y si no está haciendo la prueba primero, entonces se aplica el mismo principio). Una vez que las pruebas se escriben y pasan, no desea que cambien mientras realiza la refactorización. Si se ve obligado a probar la funcionalidad privada de la unidad, entonces probablemente significa que las pruebas unitarias en torno a la funcionalidad pública son defectuosas. Si es difícil y complejo escribir pruebas alrededor del código público, entonces tal vez su clase está haciendo demasiado o su problema no está claramente definido.
Peor aún, con el tiempo sus pruebas unitarias se convertirán en una bola y una cadena que lo ralentizarán sin agregar ningún valor (cambiar la implementación, por ejemplo, la optimización o la eliminación de la duplicación, no debería tener efecto en las pruebas unitarias). Sin embargo, el código interno debe ser probado en la unidad ya que el comportamiento / estado es observable (solo de manera restringida).
Cuando hice la prueba de la unidad por primera vez, hice todo tipo de trucos para probar cosas privadas de la unidad, pero ahora, con algunos años en mi haber, lo veo peor que una pérdida de tiempo.
Aquí hay un ejemplo un poco tonto, por supuesto en la vida real tendrías más pruebas que estas:
Digamos que tiene una clase que devuelve una lista ordenada de cadenas: debe verificar que el resultado esté ordenado, no cómo realmente clasifica esa lista. Puede comenzar su implementación con un algoritmo único que simplemente clasifique la lista. Una vez hecho esto, su prueba no necesita cambiar si luego cambia su algoritmo de clasificación. En este punto, tiene una única prueba (suponiendo que la clasificación esté integrada en su clase):
Ahora digamos que desea dos algoritmos (tal vez uno sea más eficiente en algunas circunstancias pero no en otras), entonces cada algoritmo podría (y generalmente debería) ser proporcionado por una clase diferente y su clase elige de ellos; puede verificar que esto esté sucediendo para sus escenarios elegidos utilizando simulacros, pero su prueba original sigue siendo válida y, como solo estamos verificando el comportamiento / estado observable, no necesita cambiar. Terminas con 3 pruebas:
La alternativa hubiera sido comenzar a probar el código privado dentro de su clase (no obtiene nada de esto), las pruebas anteriores me dicen todo lo que necesito saber en lo que respecta a las pruebas unitarias. Al agregar pruebas privadas, está construyendo una camisa de fuerza, ¿cuánto más trabajo sería si no solo verificara que el resultado se clasificó sino también cómo se clasifica?
Las pruebas (de este tipo) solo deberían cambiar cuando el comportamiento cambia, comenzar a escribir pruebas contra el código privado y eso desaparece.
fuente
Aquí hay otra razón: en el caso hipotético, tendría que elegir entre la unidad que prueba la API externa y las partes privadas, elegiría las partes privadas.
Si cada parte privada está cubierta por una prueba, la API que consta de estas partes privadas también debería estar cubierta por casi el 100%, excluyendo solo la capa superior. Pero es probable que sea una capa delgada.
Por otro lado, cuando solo se prueba la API, puede ser realmente difícil cubrir completamente todas las rutas de código posibles.
fuente
Es difícil lograr que la gente acepte las pruebas unitarias porque parece una pérdida de tiempo ("¡podríamos estar codificando otro proyecto para ganar dinero!") O recursivo ("¡Y luego tenemos que escribir casos de prueba para los casos de prueba!") Soy culpable de decir las dos cosas.
La primera vez que encuentras un error, tienes que enfrentar la verdad de que no eres perfecto (¡qué rápido olvidamos los programadores!) Y dices "Hmmm".
Otro aspecto de las pruebas unitarias es que el código debe escribirse para que sea comprobable. Al darse cuenta de que Some Code es fácilmente comprobable y Some Code no lo hace, un buen programador dice "Hmmm".
¿Le preguntó a su compañero de trabajo por qué las pruebas unitarias solo eran útiles para las API externas?
Una forma de mostrar el valor de las pruebas unitarias es esperar a que ocurra un error desagradable y luego mostrar cómo las pruebas unitarias podrían haberlo evitado. Eso no es para frotarlos en sus caras, eso es, en sus mentes, mover las pruebas unitarias de una Teoría de la Torre de Marfil a una realidad en las trincheras.
Otra forma es esperar hasta que el mismo error ocurra dos veces . "Uhhh, bueno Jefe, agregamos código para probar un valor nulo después del problema de la semana pasada, ¡pero el usuario ingresó una cosa vacía esta vez!"
Predicar con el ejemplo. Escriba pruebas unitarias para SU código, luego muéstrele a su jefe el valor. Luego, vea si el jefe llamará pizza para el almuerzo un día y hará una presentación.
Finalmente, no puedo decirte el alivio que siento cuando estamos a punto de presionar para obtener un empujón y obtengo una barra verde de las pruebas unitarias.
fuente
Hay dos tipos de código privado: código privado que es llamada por código público (o código privado que es llamada por código privado que es llamada por código público (o ...)) y el código privado que no finalmente no serán llamadas por el público código.
El primero ya se prueba a través de las pruebas del código público. No se puede llamar a este último y, por lo tanto, se debe eliminar, no probar.
Tenga en cuenta que cuando hace TDD es imposible que exista código privado no probado.
fuente
La prueba de unidad se trata de probar unidades de su código. Depende de usted definir qué es una unidad. Sus compañeros de trabajo definen unidades como elementos API.
De todos modos, las pruebas de API también deberían resultar en el ejercicio de código privado. Si define la cobertura del código como un indicador del progreso de las pruebas unitarias, terminará probando todo su código. Si no se ha alcanzado alguna parte del código, brinde a sus compañeros de trabajo tres opciones:
fuente