Eliminación de la “estafa de prueba de integración”: comprensión de las pruebas de colaboración y contrato [cerrado]

8

Recientemente he visto Las pruebas de integración son una estafa de JB Rainsberger y ahora estoy buscando más. Material sobre el tema. Debo decir que me sorprende lo mucho que estamos haciendo mal (es decir, las pruebas de integración cuando deberíamos hacer una prueba unitaria), intrigados por los conceptos descritos por Rainsberger pero también confundidos sobre cómo aplicarlos. Me gustaría tener más de las pruebas de colaboración y las pruebas contractuales descritas, pero no sé por dónde empezar.

Las únicas preguntas que las preguntas deben hacerse:

Cara A:

Do I ask the right question?
Can I deal with the answer?

Cara 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 un libro, un tutorial o un ejemplo que tome un ejemplo del mundo real y aplique estas ideas de micro pruebas aisladas? Idealmente, el ejemplo utiliza Java, Spring + PowerMock / Mockito / EasyMoock

Cualquier literatura que trate sobre estos conceptos en general y me ayude a entenderlos mejor sería apreciada.

Además, si hay foros en los que puedo hacer preguntas más detalladas sobre cómo realizar correctamente las pruebas unitarias y quizás incluso refactorizar el código existente y publicar ejemplos, sería bueno.

¡Gracias!

Editar - algunos pensamientos adicionales:

¿Hay una regla general, cuándo usar un simulacro y cuándo un talón para aislar una clase en prueba de sus colaboradores? ¿Se puede aplicar a las 4 preguntas?

El mejor marco de burla parece ser PowerMock, lo que me permite definir con precisión para cada prueba qué clase quiero burlar y qué debería devolver. ¿Hay algo mejor que haya utilizado para hacer las preguntas anteriores? ¿Hay buenos tutoriales por ahí que usan PowerMock para aplicar algunos o todos los principios dados a alguna parte de una pila de aplicaciones del mundo real, digamos un DAO o una GUI?

Editar 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 tendrá un nombre de usuario y una contraseña para autenticar la solicitud de guardado. Una vez autenticado, se llama a OrderManager para guardar el Order . Internamente, el administrador decide si se trata de un nuevo pedido, por lo que debe crearse o actualizarse. (Eso no debería importar al servicio web, ¿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é es exactamente lo que estoy probando aquí? Estoy pensando que debería haber pruebas para el éxito y el fracaso de la autenticación y para el éxito y el fracaso del ahorro de pedidos.

¿Pero cómo puedo dividir eso en las 4 preguntas? Mi clase en Prueba es obviamente OrderService (OS) y los colaboradores son OrderManager (OM) y AuthenticationManager . (A.M) Así que tengo las siguientes pruebas, por favor corríjame aquí, solo estoy pensando en voz alta:

SO < - > OM

  • OS le pide a OM que guarde una orden (¿qué tipo de parámetros diferentes pruebo aquí? null y Order ? ¿Importa si Order está correctamente inicializado?)
  • OM responde a una llamada guardada llamando a otro método interno, ¡¿pruebo si se invoca ese método ?!
  • El sistema operativo no debería fallar si el OM no falla
  • El sistema operativo debería fallar si OM falla

... ¿Qué más?

Y luego, por supuesto, SO < - > AM :

  • El sistema operativo solicita a AM que se autentique. ¿Supongo que pruebo cómo reacciona AM a diferentes tipos de nombre de usuario / contraseña?
  • ...

Ahora mi primera conclusión :

En cuanto a WebSerice, solo puedo probar 2 de cada 4 preguntas: Lado A. Ahora tengo que mirar el OrderManager y AuthenticationManager y ver si pueden responder las preguntas del lado B. Derecho ?

Segundo - acceso a la base de datos:

La autenticación y la persistencia de pedidos obviamente requieren algunos datos en la base de datos en un entorno de producción. Sin embargo, para mis pruebas de unidad 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 para no hacer casi nada, ya que en caso de una autenticación fallida lanzará un Exception , de lo contrario tiene el tipo de retorno void . ¿Cómo le digo a mi OrderService.save() que use mi AuthenticationManager.authenticate() simulado?

¿Y cómo configuro AuthenticationManager para no hacer nada o lanzar una excepción?

¿Puedo decirle a Spring que inyecte un AuthenticationManager simulado que no hará nada / arrojará un Exception a mi OrderService en prueba?

    
pregunta Pete 14.02.2012 - 14:10

1 respuesta

2

Esa es una pregunta realmente larga y me disculpo, pero solo repasé las partes de pensamiento adicionales.

Puedo recomendar dos libros excelentes:

No utilizan los marcos exactos que mencionaste, pero el consejo que te dan es muy valioso y se aplica fácilmente a cualquier escenario con OOD. Ambos explican detalladamente cómo configurar pruebas unitarias para aislar solo el componente que se está probando y cómo configurar objetos simulados / falsos / dependientes para dependencias remotas.

ACTUALIZACIÓN (Respuesta al siguiente comentario):

Esta respuesta es en respuesta a los OP:

  • "Me gustaría tener más de las pruebas de colaboración y las pruebas de contrato descritas": las pruebas de contrato son pruebas unitarias porque OP desea eliminar las pruebas de integración y, en cambio, probar componentes individuales en una interfaz bien definida para ese componente. Eso es una prueba de unidad y precisamente de lo que tratan esos libros.
  • "... donde puedo hacer preguntas más detalladas sobre cómo realizar correctamente las pruebas unitarias e incluso refactorizar el código existente"
  • "¿Hay una regla general, cuándo usar un simulacro y cuándo un talón para aislar una clase en prueba de sus colaboradores?" - Ambos libros tratan en gran medida de configurar objetos simulados y usarlos correctamente.
  • "¿Hay un libro, un tutorial o un ejemplo que tome un ejemplo del mundo real y aplique estas ideas de micro pruebas aisladas?" - Sí, esto se denomina prueba de unidad y los dos libros que enumeré son excelentes para explicar esto.

Como señaló OP, las pruebas de integración tienen muchos problemas porque tienden a ser muy complejas y difíciles de escribir muy rápido, una buena alternativa es la prueba unitaria y la prueba de cada clase de forma aislada frente a sus interfaces públicas. Además de las pruebas unitarias, ambos libros también analizan las pruebas de integración y mencionan dónde deben y no deben usarse.

Además, después de pasar por alto la pregunta de OP, parece que mucha incertidumbre gira en torno al uso de objetos simulados y ambos libros realmente se centran en cómo usar correctamente los objetos simulados (aunque no mencionan Spring o marcos simulados específicos)

    
respondido por el DXM 14.02.2012 - 14:24

Lea otras preguntas en las etiquetas