Recientemente he visto las pruebas de integración son una estafa de JB Rainsberger y ahora estoy buscando más material sobre el tema. Tengo que decir que estoy sorprendido por lo mucho que estamos haciendo mal (es decir, las pruebas de integración cuando deberíamos hacer pruebas unitarias), intrigado por los conceptos descritos por Rainsberger, pero también confundido acerca de cómo aplicarlos. Me gustaría tener más de las pruebas de colaboración y pruebas de contrato descritas , pero no sé por dónde empezar.
Las únicas cosas que se me quedaron atrapadas en la mente son las 4 preguntas que deben hacer las pruebas:
Lado a:
Do I ask the right question?
Can I deal with the answer?
Lado B:
Can I answer a question?
Do I answer correctly?
Pero, ¿cómo aplico esto a algún método aleatorio en mi pila de aplicaciones?
¿Existe algún libro, tutorial o ejemplo que tome un ejemplo del mundo real y aplique estas ideas de micro pruebas aisladas? Idealmente, el ejemplo usa Java, Spring + PowerMock / Mockito / EasyMoock
Cualquier literatura que trate estos conceptos en general y me ayude a comprenderlos mejor sería apreciada.
Además, si hay foros por ahí donde puedo hacer preguntas más detalladas sobre cómo realizar correctamente las pruebas unitarias y tal vez incluso refactorizar el código existente y publicar ejemplos sería bueno.
¡Gracias!
Editar - algunos pensamientos adicionales:
¿Existe una regla general, cuándo usar un simulacro y cuándo un trozo para aislar una clase bajo prueba de sus colaboradores? ¿Se puede aplicar a las 4 preguntas?
El mejor marco de simulación parece ser PowerMock, lo que me permite definir con precisión para cada examen de qué clase me quiero haber burlado y qué debería devolver o ¿hay algo mejor que haya utilizado para hacer las preguntas anteriores? ¿Existen buenos tutoriales que usen PowerMock para aplicar algunos o todos los principios dados a alguna parte de una pila de aplicaciones del mundo real, por ejemplo, un DAO o una GUI?
Edición 2: un ejemplo
Solo un ejemplo del tipo de métodos que quiero probar y mis pensamientos.
Tengo un servicio web que guarda pedidos. En esta etapa no estamos demasiado preocupados por la mejor seguridad, por lo que para tener algo, el servicio también tomará un nombre de usuario y una contraseña para autenticar la solicitud de guardado. Una vez autenticado, OrderManager
se llama para guardar el Order
. Internamente, el administrador decide si se trata de un nuevo pedido, por lo que debe crearse o uno existente que debe actualizarse. (Eso no debería importarle a WebSerice, ¿verdad?)
@WebService
public class OrderService {
@Inject
private AuthenticationManager authenticationManager;
@Inject
private OrderManager orderManager;
public void save(String username, String password, Order order) {
authenticationManager.authenticate(username, password);
try {
orderManager.save(orde);
} finally {
authenticationManager.logout();
}
}
Ahora me pregunto: ¿qué estoy probando exactamente aquí? Estoy pensando que debería haber pruebas para el éxito y el fracaso de la autenticación y para el ahorro y el éxito del pedido.
Pero, ¿cómo puedo dividir eso en las 4 preguntas? Mi clase bajo Prueba es obviamente OrderService
(OS) y los colaboradores son OrderManager
(OM) y AuthenticationManager
. (AM) Así que tengo las siguientes pruebas, corríjanme aquí, solo estoy pensando en voz alta:
OS <--> OM
- OS pide OM para salvar una orden (qué tipo de diferentes parámetros puedo probar aquí?
null
YOrder
? Qué importa siOrder
se ha inicializado correctamente?) - OM responde una llamada guardada llamando a algún otro método interno, ¿II prueba si ese método se invoca?
- El sistema operativo no debe fallar si OM no falla
- El sistema operativo debería fallar si OM falla
... ¿Qué más?
Y luego, por supuesto, OS <--> AM :
- El sistema operativo le pide a AM que se autentique. ¿Supongo que pruebo cómo reacciona el AM a los diferentes tipos de nombre de usuario / contraseña?
- ...
Ahora mi primera conclusión :
En lo que respecta a la WebSerice sólo puedo probar 2 de cada 4 preguntas: A. Lado Ahora tengo que mirar el OrderManager
e AuthenticationManager
y ver si pueden responder a las preguntas de la cara B. Justo?
En segundo lugar, acceso a la base de datos:
La autenticación y el orden persistente obviamente requieren algunos datos en la base de datos en un entorno de producción. Sin embargo, para mis pruebas unitarias no las necesitaré, así que me burlaré de las llamadas para devolver el resultado deseado, ¿verdad? ¿Pero cómo me burlo de esto?
Necesito AuthenticationManager.authenticate
que prácticamente no haga nada, ya que en caso de una autenticación fallida, arrojará una Exception
, de lo contrario, tiene el tipo de retorno void
. ¿Cómo le digo a mi OrderService.save()
que use mi burla AuthenticationManager.authenticate()
?
¿Y cómo configuro la AuthenticationManager
configuración para no hacer nada o lanzar una excepción?
¿Puedo decirle a Spring que inyecte una burla AuthenticationManager
que no hará nada / que arroje una Exception
en mi OrderService
prueba?
Respuestas:
Esa es una pregunta muy larga y me disculpo, pero solo hojeé las partes de pensamiento adicionales.
Puedo recomendar dos excelentes libros:
No utilizan los marcos exactos que mencionó, pero el consejo que le dan es muy valioso y se aplica fácilmente a cualquier escenario con OOD. Ambos entran en gran detalle sobre cómo configurar las pruebas unitarias para aislar solo el componente que se está probando y cómo configurar objetos simulados / falsos / stub en dependencias remotas.
ACTUALIZACIÓN (Respuesta al comentario a continuación):
Esta respuesta es en respuesta a los OP:
Como OP señaló, las pruebas de integración pueden tener muchos problemas porque tienden a volverse muy complejas y difíciles de escribir muy rápido, una buena alternativa es la prueba unitaria y probar cada clase aisladamente contra sus interfaces públicas. Además de las pruebas unitarias, ambos libros discuten las pruebas de integración y mencionan dónde se debe y no se debe usar.
Además, después de pasar por alto la pregunta de OP un poco más, parece que mucha incertidumbre gira específicamente en torno al uso de objetos simulados y ambos libros realmente se enfocan en cómo usar adecuadamente los objetos simulados (aunque no mencionan Spring o marcos simulados específicos). )
fuente