2008-11-11 37 views
35

Estoy trabajando en un proyecto Spring MVC y tengo pruebas unitarias para todos los componentes en el árbol fuente.Pruebas unitarias vs pruebas de integración con Spring

Por ejemplo, si tengo un controlador HomeController, que necesita tener un LoginService inyecta en él, entonces en mi unidad de prueba HomeControllerTest I simplemente una instancia del objeto de forma normal (fuera de la primavera) e inyectar la propiedad:

protected void setUp() throws Exception { 
    super.setUp(); 
    //... 
    controller = new HomeController(); 
    controller.setLoginService(new SimpleLoginService()); 
    //... 
} 

Esto funciona muy bien para probar cada componente como una unidad aislada, excepto ahora que tengo unas pocas docenas de clases en el proyecto, después de escribir una clase y escribir una prueba de unidad exitosa para ello, me olvido de actualizar mi Spring MVC archivo de contexto que realiza el cableado real en la aplicación implementada. Descubrí que olvidé actualizar el archivo de contexto cuando implementé el proyecto en Tomcat y encontré un montón de NullPointers de beans no conectados.

lo tanto, aquí están mis preguntas:

  1. Este es mi primer proyecto de Primavera - ¿Es normal para crear pruebas unitarias para los granos individuales, como lo he hecho, y luego crear un segundo conjunto de pruebas (pruebas de integración) para probar que todo funciona como se espera con el contexto de la aplicación real? ¿Existe una mejor práctica establecida para esto?

  2. Además, ¿cómo separa las pruebas unitarias de las pruebas de integración? Tengo todo el código fuente en src, la unidad prueba en test - ¿debería haber una segunda carpeta de prueba (como test-integration) para casos de prueba de integración?

Dado que este es mi primer proyecto de Primavera, tengo curiosidad por cómo los demás por lo general van haciendo este tipo de cosas - y en lugar de reinventar la rueda y no me pido al resto de la comunidad.

Respuesta

32

No puedo hablar de ser una buena práctica, pero esto es lo que hice en el pasado.

Las pruebas unitarias:

  • crear pruebas unitarias para los granos no triviales (es decir, la mayoría de la primavera granos relacionados)
  • Uso burla de para los servicios inyectados en práctica (es decir, la mayoría, si no todos el tiempo).
  • Utilice una convención de nomenclatura estándar para estas pruebas en el directorio del proyecto test. Usar Test o TestCase como un prefijo o sufijo para el nombre de clase parece ser ampliamente practicado.

pruebas de integración:

  • crear una AbstractIntegrationTestCase que establece una SpringWebApplicationContext para su uso en clases de prueba intetgration.
  • Utilice una convención de nomenclatura para pruebas de integración en el directorio test. He usado IntTest o IntegrationTest como prefijo o sufijo para estas pruebas.

establecer tres Ant test objetivos:

  1. test-all (o como se quiera llamarlo): unidad de ejecución e Integración pruebas
  2. prueba: Pruebas de unidad de ejecución (sólo porque test parece ser el uso más común para la unidad de prueba
  3. test-integración:. ejecutar las pruebas de integración

Como se ha señalado, puede usar las convenciones de nomenclatura que tengan sentido para su proyecto.

En cuanto a separar la unidad de las pruebas de integración en un directorio separado, no creo que importe mientras los desarrolladores y sus herramientas puedan encontrarlas y ejecutarlas fácilmente.

A modo de ejemplo, el último proyecto Java que trabajé con Spring utilizado exactamente lo que se ha descrito anteriormente, con las pruebas de integración y pruebas de unidad que viven en el mismo directorio test. Los proyectos de Grails, por otro lado, separan explícitamente los directorios de pruebas de integración y unidad bajo un directorio general de pruebas.

+1

Esto suena como una buena estrategia. Pero con las pruebas unitarias y las pruebas de integración en los mismos directorios, Eclipse no tiene forma de diferenciarlos, ¿verdad? Las únicas opciones de Eclipse para ejecutar pruebas junit es ejecutar una sola o ejecutar todas en una determinada carpeta; no puede dividirlas por nombre como Ant. –

+0

Tuve que volver atrás y consultar Eclipse; está en lo cierto, no veo una manera de diferenciar las pruebas si están en el mismo directorio. Mi último proyecto de primavera fue hecho en Idea/Intellij y ha sido lo suficientemente largo como para no recordar exactamente cuál era la configuración de IDE. –

4

Gran parte de la tediosa contabilidad doble con resorte desaparece si también se cambia a un régimen puramente anotado, donde anota todos sus beans con @Component, @Controller, @Service y @Repository. Simplemente agregue @Autowired a los atributos que necesita para ser inyectado.

Consulte la sección 3.11 del manual de referencia del muelle. http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config

En una nota relacionada, hemos estado usando las pruebas de unidad/Integratrion de división que describe KenG. En mi régimen más reciente, también presentamos una tercera "clase" de pruebas, "ComponentTests". Funcionan con cableado completo de muelles, pero con implementaciones de stub cableadas (utilizando filtros de componentes y anotaciones en primavera).

La razón por la que hicimos esto se debía a que para algunos de la capa de "servicio" se termina con una cantidad terrible de la lógica de cableado codificado a mano para conectar manualmente el frijol, y, a veces tan pocas cantidades de mock-objetos. 100 líneas de cableado para 5 líneas de prueba no son infrecuentes. Las pruebas de componentes alivian este problema.

+0

Lamentablemente sigo usando Java 1.4 :( –

0

Cuando he creado pruebas de integración para aplicaciones web, las he puesto en un directorio aparte. Se crean utilizando jUnit o TestNG e interactúan con el sistema bajo prueba usando algo como Selenium que llega a las páginas web como si fueran usuarios. El ciclo sería así: compilar, ejecutar pruebas unitarias, crear la aplicación web, implementarla en un servidor en ejecución, ejecutar las pruebas, anular la implementación de la aplicación e informar los resultados. La idea es probar todo el sistema.

2

Utilice la interfaz InitializingBean (implementa un método "afterPropertiesSet") o especifique un método init para sus beans. InitializingBean es generalmente más fácil porque no necesita recordar agregar el método init a sus beans.

Utilice afterPropertiesSet para asegurarse de que todo se inyecte como no nulo, si es nulo, genere una excepción.

0

Con respecto a la ejecución de pruebas unitarias por separado de las pruebas de integración, pongo todo este último en un directorio de pruebas de integración y ejecutarlos usando IDE/Ant utilizando un enfoque como this. Funciona para mi.

6

Unos pocos puntos aislados:

Sí, es un enfoque común a la primavera de pruebas - pruebas de unidad separada y pruebas de integración, donde el primero no cargar cualquier contexto primavera.

Para las pruebas de su unidad, tal vez considere la burla para asegurarse de que sus pruebas se centren en un módulo aislado.

Si sus pruebas están conectadas en un montón de dependencias, entonces no son realmente pruebas unitarias. Son pruebas de integración en las que está cableando dependencias que usan inyección nueva en lugar de dependencia. ¡Una pérdida de tiempo y esfuerzo duplicado cuando su aplicación de producción utiliza Spring!

Las pruebas de integración básica para mostrar los contextos de Spring son útiles.

La anotación @required puede ayudarlo a asegurarse de que detecta las dependencias requeridas en su cableado de Spring.

Tal vez busque en Maven, que le dará fases explícitas para vincular su unidad y las pruebas de integración. Maven es ampliamente utilizado en la comunidad de Spring.

0

la diferencia entre la prueba unitaria y la prueba de integración es que la prueba unitaria no carga necesariamente su contexto, se está enfocando en el código que ha escrito - funciona rápidamente, es decir con y sin excepciones, burlándose de cualquier depende lo llama Pero en el caso de las pruebas de integración, carga contexto y realiza una prueba de extremo a extremo como escenarios reales.

Cuestiones relacionadas