Titulé la pregunta en broma porque estoy seguro de que "depende", pero tengo algunas preguntas específicas.
Al trabajar en un software que tiene muchas capas profundas de dependencia, mi equipo se ha acostumbrado a utilizar la burla de manera bastante extensa para separar cada módulo de código de las dependencias que se encuentran debajo.
Por lo tanto, me sorprendió que Roy Osherove sugiriera en este video que deberías usar burlarte solo como el 5% del tiempo. Supongo que estamos sentados en algún lugar entre 70-90%. He visto otra guía similar de vez en cuando también.
Debería definir lo que considero que son dos categorías de "pruebas de integración" que son tan distintas que realmente deberían recibir nombres diferentes: 1) Pruebas en proceso que integran múltiples módulos de código y 2) Pruebas fuera de proceso que hablan a bases de datos, sistemas de archivos, servicios web, etc. Es el tipo # 1 lo que me preocupa, las pruebas que integran múltiples módulos de código en proceso.
Gran parte de la orientación comunitaria que he leído sugiere que debería preferir una gran cantidad de pruebas unitarias aisladas y de grano fino y una pequeña cantidad de pruebas integrales de integración de extremo a extremo, porque las pruebas unitarias le brindan información precisa sobre exactamente dónde Es posible que se hayan creado regresiones, pero las pruebas groseras, que son difíciles de configurar, en realidad verifican una mayor funcionalidad de extremo a extremo del sistema.
Dado esto, parece necesario hacer un uso bastante frecuente de la burla para aislar estas unidades de código separadas.
Dado un modelo de objeto de la siguiente manera:
... También considere que la profundidad de dependencia de nuestra aplicación es mucho más profunda de lo que podría caber en esta imagen, de modo que hay varias capas N entre la capa 2-4 y la capa 5-13.
Si quiero probar alguna decisión lógica simple que se toma en la unidad n. ° 1, y si cada dependencia se inyecta al constructor en el módulo de código que depende de él, de modo que, por ejemplo, 2, 3 y 4 se inyectan al constructor en el módulo 1 en la imagen, preferiría inyectar simulacros de 2, 3 y 4 en 1.
De lo contrario, necesitaría construir instancias concretas de 2, 3 y 4. Esto puede ser más difícil que simplemente escribir algo más. A menudo 2, 3 y 4 tendrán requisitos de constructor que pueden ser difíciles de satisfacer y de acuerdo con el gráfico (y de acuerdo con la realidad de nuestro proyecto), necesitaré construir instancias concretas de N a 13 para satisfacer a los constructores de 2, 3 y 4.
Esta situación se vuelve más desafiante cuando necesito que 2, 3 o 4 se comporten de cierta manera para poder probar la simple decisión lógica en el n. ° 1. Es posible que necesite comprender y "razonar mentalmente" sobre todo el gráfico / árbol de objetos de una vez para que 2, 3 o 4 se comporten de la manera necesaria. A menudo parece mucho más fácil hacer myMockOfModule2.Setup (x => x.GoLeftOrRight ()). Returns (new Right ()); para probar que el módulo 1 responde como se esperaba cuando el módulo 2 le dice que vaya a la derecha.
Si tuviera que probar instancias concretas de 2 ... N ... 13 en conjunto, las configuraciones de prueba serían muy grandes y en su mayoría duplicadas. Las fallas en las pruebas podrían no hacer un muy buen trabajo al identificar las ubicaciones de las fallas de regresión. Las pruebas no serían independientes ( otro enlace de soporte ).
Por supuesto, a menudo es razonable realizar pruebas de la capa inferior basadas en el estado, en lugar de la interacción, ya que esos módulos rara vez tienen más dependencia. Pero parece que la burla es casi necesaria, por definición, para aislar cualquier módulo que esté por encima del más bajo.
Dado todo esto, ¿alguien puede decirme lo que podría estar perdiendo? ¿Está nuestro equipo sobreutilizando simulacros? ¿O tal vez hay alguna suposición en la guía de pruebas de unidad típica de que las capas de dependencia en la mayoría de las aplicaciones serán lo suficientemente superficiales como para que sea razonable probar todos los módulos de código integrados juntos (haciendo nuestro caso "especial")? O quizás de manera diferente, ¿nuestro equipo no está limitando adecuadamente nuestros contextos limitados?
fuente
Or is there perhaps some assumption in typical unit testing guidance that the layers of dependency in most applications will be shallow enough that it is indeed reasonable to test all of the code modules integrated together (making our case "special")?
<- Esto.Respuestas:
No a primera vista.
Si tiene 1..13 módulos, cada uno debe tener sus propias pruebas unitarias, y todas las dependencias (no triviales, no confiables) deben reemplazarse por versiones de prueba. Eso puede significar simulacros, pero algunas personas son pedantes con los nombres, por lo que falsificaciones, cuñas, objetos nulos ... algunas personas se refieren a todas las implementaciones de prueba como "simulacros". Esta podría ser la fuente de la confusión sobre cuánto es "correcto".
Personalmente, llamo a todos los objetos de prueba "simulacros" porque a menudo no es útil distinguir entre la variedad de ellos. Mientras mantengan mis pruebas unitarias rápidas, aisladas y resistentes ... No me importa cómo se llamen.
fuente