5

imaginar un proyecto Java construido utilizando Maven para los que tengo:Cómo detener la fase de verificación de Maven al reconstruir el artefacto?

  • algunas corrientes rápidas de pruebas unitarias que:
    • desarrolladores deben ejecutarse antes de cometer
    • mi servidor CI (Hudson, Fwiw) debería funcionar al detectar una nueva confirmación, dar retroalimentación casi instantánea en caso de fallos
  • algunas pruebas de aceptación automatizados de marcha lenta que:
    • los desarrolladores pueden ejecutar si así lo desean, p. para reproducir y corregir los fallos
    • mi servidor de CI debe ejecutar después de ejecutar correctamente la unidad de prueba

Este parece ser un escenario típico. Actualmente, estoy corriendo:

  • las pruebas de unidad en la fase de "prueba"
  • las pruebas de aceptación en la fase de "verificar"

Hay dos puestos de trabajo de CI configurados tanto, que apunta a rama del proyecto VCS:

  1. "Commit Etapa", que se ejecuta "mvn package" (compilar y prueba de la unidad del código, construir el artefacto), que si tiene éxito, desencadena:
  2. "Pruebas Automatizado aceptación", que corre "mvn verificar" (configurar, ejecutar y derribar las pruebas de aceptación)

El problema es que las pruebas de la unidad de trabajo 2 y construye el bajo prueba artefacto en todo de nuevo (porque la fase de verificación invoca automáticamente la fase del paquete). Esto no es deseable por varias razones (en orden decreciente de importancia):

  • el artefacto creado por el trabajo 2 puede no ser idéntica a la creada por el trabajo 1 (por ejemplo, si se ha producido un nuevo commit en el ínterin)
  • alarga el ciclo de retroalimentación para el desarrollador que hizo el envío de datos (es decir, toma más tiempo para que se enteran de que rompieron la construcción)
  • desperdicia recursos en el servidor IC

Así que mi pregunta es, ¿cómo puedo configurar empleo 2 para usar el artefacto creado por el trabajo 1?

Me doy cuenta de que solo podría tener un trabajo de CI que ejecute "mvn verify", que crearía el artefacto solo una vez, pero quiero tener los trabajos de CI separados descritos anteriormente para implementar una canalización de despliegue de estilo Farley .


En caso de que ayuda a nadie, aquí está la completa Maven 2 POM del "Proyecto 2" en la respuesta aceptada:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>com.example.cake</groupId> 
    <artifactId>cake-acceptance</artifactId> 
    <version>1.0</version> 
    <packaging>jar</packaging> 
    <name>Cake Shop Acceptance Tests</name> 
    <description> 
     Runs the automated acceptance tests for the Cake Shop web application. 
    </description> 
    <build> 
     <plugins> 
      <!-- Compiler --> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>2.3.1</version> 
       <configuration> 
        <source>${java.version}</source> 
        <target>${java.version}</target> 
       </configuration> 
      </plugin> 
      <!-- Suppress the normal "test" phase; there's no unit tests --> 
      <plugin> 
       <artifactId>maven-surefire-plugin</artifactId> 
       <version>2.5</version> 
       <configuration> 
        <skipTests>true</skipTests> 
       </configuration> 
      </plugin> 
      <!-- Cargo (starts and stops the web container) --> 
      <plugin> 
       <groupId>org.codehaus.cargo</groupId> 
       <artifactId>cargo-maven2-plugin</artifactId> 
       <version>1.0.5</version> 
       <executions> 
        <execution> 
         <id>start-container</id> 
         <phase>pre-integration-test</phase> 
         <goals> 
          <goal>start</goal> 
         </goals> 
        </execution> 
        <execution> 
         <id>stop-container</id> 
         <phase>post-integration-test</phase> 
         <goals> 
          <goal>stop</goal> 
         </goals> 
        </execution> 
       </executions> 
       <configuration> 
        <!-- Don't wait for CTRL-C after starting the container --> 
        <wait>false</wait> 

        <container> 
         <containerId>jetty7x</containerId> 
         <type>embedded</type> 
         <timeout>20000</timeout> 
        </container> 

        <configuration> 
         <properties> 
          <cargo.servlet.port>${http.port}</cargo.servlet.port> 
         </properties> 
         <deployables> 
          <deployable> 
           <groupId>${project.groupId}</groupId> 
           <artifactId>${target.artifactId}</artifactId> 
           <type>war</type> 
           <properties> 
            <context>${context.path}</context> 
           </properties> 
          </deployable> 
         </deployables> 
        </configuration> 
       </configuration> 
      </plugin> 
      <!-- Failsafe (runs the acceptance tests) --> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-failsafe-plugin</artifactId> 
       <version>2.6</version> 
       <executions> 
        <execution> 
         <id>integration-test</id> 
         <goals> 
          <goal>integration-test</goal> 
         </goals> 
        </execution> 
        <execution> 
         <id>verify</id> 
         <goals> 
          <goal>verify</goal> 
         </goals> 
        </execution> 
       </executions> 
       <configuration> 
        <includes> 
         <include>**/*Test.java</include> 
        </includes> 
        <skipTests>false</skipTests> 
       </configuration> 
      </plugin> 
     </plugins> 
    </build> 
    <dependencies> 
      <!-- Add your tests' dependencies here, e.g. Selenium or Sahi, 
       with "test" scope --> 
     <dependency> 
      <!-- The artifact under test --> 
      <groupId>${project.groupId}</groupId> 
      <artifactId>${target.artifactId}</artifactId> 
      <version>${target.version}</version> 
      <type>war</type> 
     </dependency> 
    </dependencies> 
    <properties> 
     <!-- The artifact under test --> 
     <target.artifactId>cake</target.artifactId> 
     <target.version>0.1.0-SNAPSHOT</target.version> 
     <context.path>${target.artifactId}</context.path> 
     <http.port>8081</http.port> 
     <java.version>1.6</java.version> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    </properties> 
</project> 

Tenga en cuenta que a pesar de que este proyecto "pruebas" no crea un artefacto, tiene que usar algún tipo de empaque (utilicé "jar" aquí), de lo contrario no se ejecutarán pruebas en la fase de verificación.

+0

Solo para el beneficio de aquellos que desean comprender mejor el enfoque, ver Entrega Continua por Jez Humble y David Farley. –

+0

¡Exactamente el libro que provocó este esfuerzo! Bien vale la pena el precio. –

Respuesta

4

Pruebe dos proyectos maven. El primero contiene las pruebas de construcción y unidad. Instala los artefactos en su repositorio local. El segundo trabajo ejecuta el segundo proyecto maven, que declara los artefactos del primer proyecto como dependencias y ejecuta las pruebas funcionales.

No estoy seguro si el escenario que acabo de describir es posible, pero creo que sí.

Para una mejora rápida puede eludir la prueba de unidad con -Dmaven.test.skip=true. Si pasa el número de revisión de su código en su scm al segundo trabajo, debería poder consultar el mismo código fuente.

También puede verificar en el plugin SCM Workspace SCM. Esto podría ofrecerle algunas opciones adicionales.

+1

Me gusta la idea de "dos proyectos maven"; Voy a darle un giro. Suena como algo que John Smart recomendó en una presentación de diapositivas en CI hace aproximadamente dos años, pero no estaba seguro de los detalles o de si aún se consideraba como la mejor práctica. –

+0

Funcionó muy bien; He adjuntado el POM del segundo proyecto a la pregunta, para cualquier otra persona que quiera probarlo. –

0

Así que mi pregunta es: ¿Cómo se configura trabajo 2 para usar el artefacto creado por trabajo 1?

No puede.

No es necesario. El Maven Build lifecycle está configurado de una manera que parece que satisfará sus necesidades. El ciclo de vida de la prueba solo ejecutará los junits rápidos. El paquete construye su estado final sin ejecutar la verificación.

Solo necesita un trabajo de CI. Cuando el CI ejecuta su ciclo de vida de instalación/instalación del administrador, si los puntos suspensivos fallan la construcción falla, los scripts de verificación no se ejecutarán.

+1

Lo que dices es cierto, pero no cumple con mi requisito (no explícito) de que haya dos trabajos de CI separados, ya que estoy creando una canalización de implementación y necesito visibilidad de qué revisiones pasaron la etapa de confirmación y cuáles también pasaron el etapa de aceptación. He aclarado la pregunta. –

+0

ah, tiene sentido :) – Andy

0

Puede definir un perfil de Maven que se utilizará para ejecutar solo las pruebas de integración. Lo hago mucho.

Algo como esto:

<profiles> 
    <profile> 
     <id>integration</id> 
     <activation> 
      <activeByDefault>false</activeByDefault> 
     </activation> 
     <build> 
      <plugins> 
       <plugin> 
        <artifactId>maven-surefire-plugin</artifactId><version>2.17</version> 
        <configuration> 
         <skipTests>true</skipTests> 
        </configuration> 
       </plugin> 
       <plugin> 
        <artifactId>maven-war-plugin</artifactId><version>2.4</version> 
        <configuration> 
         <outputDirectory>/tmp</outputDirectory> 
        </configuration> 
       </plugin> 
      </plugins> 
     </build> 
    </profile> 
</profiles> 

debe invocar esto con:

mvn verify -Pintegration 

Desafortunadamente el plugin GUERRA no puede ser omitido, pero usted puede enviar su salida a algún lugar fuera del camino (He usado/tmp). Si realmente desea guardar milisegundos, también puede hacer que ignore los recursos web (excepto web.xml, no funcionará sin eso).

También puede usar el perfil para saltar cualquier otros complementos que se esté ejecutando, por ejemplo, el plug-in de montaje, Cobertura, el PMD, etc.

0

perfil Maven que ejecuta sólo las pruebas de integración (as suggested here) no es suficiente . También debe asegurarse de que la configuración de maven-compiler-plugin tenga useIncrementalCompilation = false. Al ejecutar el perfil de esta manera, no se volverá a compilar automáticamente, p.:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-compiler-plugin</artifactId> 
    <version>3.3</version> 
    <configuration> 
     <source>1.8</source> 
     <target>1.8</target> 
     <useIncrementalCompilation>false</useIncrementalCompilation> 
    </configuration> 
</plugin> 
0

Sé que ha pasado mucho tiempo, pero esto es así indexados y hacer lo que pidieron ninguna de las respuestas, pero he encontrado algo que funciona:

mvn failsafe:integration-test 

Esto va en las pruebas directamente, sin pasar por todos los pasos intermedios de la construcción del proyecto. Es posible que desee agregar failsafe:verify después de él.

Cuestiones relacionadas