Junit: pruebas de integración de división y pruebas unitarias


He heredado una carga de prueba Junit, pero estas pruebas (aparte de la mayoría no funciona) son una mezcla de pruebas unitarias reales y pruebas de integración (que requieren sistemas externos, db, etc.).

Así que estoy tratando de pensar en una manera de separarlos realmente, para que pueda ejecutar la prueba unitaria agradable y rápidamente y las pruebas de integración después de eso.

Las opciones son..

  1. Divídalos en directorios separados.

  2. Mover a Junit4 (desde v3) y anotar las clases para separarlos.

  3. Use una convención de nomenclatura de archivos para decir qué es una clase, es decir, AdapterATest y Prueba de rendimiento del adaptador.

3 tiene el problema de que Eclipse tiene la opción de "Ejecutar todas las pruebas en el proyecto/paquete o carpeta seleccionados". Así que sería muy difícil simplemente ejecutar las pruebas de integración.

2: se corre el riesgo de que los desarrolladores puedan comenzar a escribir pruebas de integración en clases de prueba unitaria y simplemente se complica.

1: Parece como la solución más limpia, pero mi instinto dice que debe haber una mejor solución por ahí.

Así que esa es mi pregunta, ¿cómo se rompen mucho pruebas de integración y pruebas unitarias adecuadas?

Author: Péter Török, 2010-04-09

6 answers

Actualmente uso directorios separados debido a la política organizativa (y el legado de Junit 3), pero estoy buscando hacer la transición a las anotaciones yo mismo ahora que estoy en Junit 4.

No me preocuparía demasiado que los desarrolladores pusieran pruebas de integración en sus clases de prueba unitaria; agregue una regla en sus estándares de codificación si es necesario.

Estoy interesado en saber qué tipo de otras soluciones podría haber aparte de anotaciones o separando físicamente las clases..

 9
Author: Steven Mackenzie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-09 10:43:03

Puedes dividirlos muy fácilmente usando categorías JUnit y Maven.

Esto se muestra muy, muy brevemente a continuación dividiendo la unidad y las pruebas de integración.

Definir Una Interfaz De Marcador

El primer paso para agrupar una prueba usando categorías es crear una interfaz de marcador.

Esta interfaz se utilizará para marcar todas las pruebas que desee ejecutar como pruebas de integración.

public interface IntegrationTest {}

Marque su prueba clases

Agregue la anotación de categoría a la parte superior de su clase de prueba. Toma el nombre de tu nueva interfaz.

import org.junit.experimental.categories.Category;
@Category(IntegrationTest.class)
public class ExampleIntegrationTest{
  @Test
  public void longRunningServiceTest() throws Exception {
  }
}

Configurar Pruebas unitarias Maven

La belleza de esta solución es que nada cambia realmente para el lado de la prueba unitaria de las cosas.

Simplemente agregamos alguna configuración al plugin maven surefire para hacer que ignore cualquier prueba de integración.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <includes>
      <include>**/*.class</include>
    </includes>
    <excludedGroups>com.test.annotation.type.IntegrationTest</excludedGroups>
  </configuration>
</plugin>

Cuando realiza una prueba limpia de mvn solo sus pruebas unitarias sin marcar correrá.

Configurar Pruebas de integración Maven

Una vez más, la configuración para esto es muy simple.

Para ejecutar solo las pruebas de integración, use esto:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <groups>com.test.annotation.type.IntegrationTest</groups>
  </configuration>
</plugin>

Si envasa esto en un perfil con id IT, solo puede ejecutar las pruebas rápidas usando mvn clean install. Para ejecutar solo las pruebas integration/slow, use mvn clean install -P IT.

Pero la mayoría de las veces, querrá ejecutar las pruebas rápidas por defecto y todas las pruebas con -P IT. Si ese es el caso, entonces usted tiene para usar un truco:

<profiles>
    <profile>
        <id>IT</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <excludedGroups>java.io.Serializable</excludedGroups> <!-- An empty element doesn't overwrite, so I'm using an interface here which no one will ever use -->
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

Como puede ver, estoy excluyendo las pruebas que están anotadas con java.io.Serializable. Esto es necesario porque el perfil heredará la configuración predeterminada del complemento Surefire, por lo que incluso si dice <excludedGroups/> o <excludedGroups></excludedGroups>, se utilizará el valor com.test.annotation.type.IntegrationTest.

Tampoco puedes usar none ya que tiene que ser una interfaz en el classpath (Maven lo comprobará).

Notas:

  • La dependencia a surefire-junit47 solo es necesaria cuando Maven no cambia a la JUnit 4 runner automáticamente. Usando el elemento groups o excludedGroups debería activar el interruptor. Ver aquí.
  • La mayor parte del código anterior fue tomado de la documentación del plugin Maven Failsafe. Vea la sección "Usando categorías JUnit" en esta página.
  • Durante mis pruebas, descubrí que esto incluso funciona cuando usas @RunWith() anotaciones para ejecutar suites o pruebas basadas en Spring.
 124
Author: John Dobie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-14 16:11:39

Utilizamos Maven Surefire Plugin para ejecutar pruebas unitarias y Maven Failsafe Plugin para ejecutar pruebas de integración. Las pruebas unitarias siguen las convenciones de nomenclatura **/Test*.java **/*Test.java **/*TestCase.java, integration tests - **/IT*.java **/*IT.java **/*ITCase.java. Así que en realidad es su opción número tres.

En un par de proyectos usamos TestNG y definimos diferentes grupos de prueba para integration/unit tests, pero esto probablemente no sea adecuado para usted.

 34
Author: lexicore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-09 12:58:14

Me movería hasta Junit4 solo por tenerlo :)

Podría separarlos en diferentes conjuntos de pruebas. No se como están organizados en Junit3 pero debería ser fácil en Junit4 solo construir suites de prueba y poner todas las pruebas unitarias reales en una de ellas y luego usar una segunda suite para las pruebas de integración.

Ahora defina una configuración de ejecución para ambas suites en eclipse y podrá ejecutar fácilmente una sola suite. Estas suites también podrían iniciarse desde un proceso automatizado lo que le permite ejecutar las pruebas unitarias cada vez que cambia la fuente y tal vez las pruebas de integración (si son realmente grandes) solo una vez al día o una vez por hora.

 11
Author: Janusz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-09 12:31:56

Usando IfProfileValue anotación de primavera hace posible lograr esto sin un complemento maven o una configuración requerida.

Anote las clases o métodos de prueba de integración usando IfProfileValue

import org.springframework.test.annotation.IfProfileValue;

@IfProfileValue(name="test-groups", value="integration")
public class ExampleIntegrationTest{
    @Test
    public void longRunningServiceTest() throws Exception {
    }
} 

Para ejecutar usando pruebas unitarias solamente:

mvn clean test

Para ejecutar usando pruebas de integración y pruebas unitarias:

mvn clean test -Dtest-groups=integration

Además, "Ejecutar todas las pruebas" en un IDE solo ejecutaría pruebas unitarias. Agregue -Dtest-groups=integration a los argumentos de la VM para ejecutar tanto la integración como las pruebas unitarias.

 8
Author: Mit Mehta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-12 20:40:43

No hay una respuesta correcta. Como has explicado, hay varias maneras de hacerlo que funcionarán. He hecho tanto el esquema de nombres de archivos y dividir las cosas en diferentes directorios.

Parece que dividir la cosa en diferentes directorios podría funcionar mejor para usted, y eso me parece un poco más claro, así que me inclinaría hacia eso.

No creo que intentaría anotaciones porque eso me parece más fino. ¿Realmente quieres estos dos tipos de pruebas mezclados en el mismo archivo? No lo haría.

 5
Author: ndp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-11 04:42:46