Question

Imaginez un projet Java construit en utilisant Maven pour que j'ai:

  • certains tests unitaires à fonctionnement rapide que:
    • Les développeurs doivent exécuter avant de commettre
    • mon serveur CI (Hudson, FWIW) devrait fonctionner lors de la détection d'un nouveau commit, donner une rétroaction presque instantanée en cas de défaillance
  • certains tests d'acceptation automatique à vitesse lente que:
    • les développeurs peuvent exécuter s'ils choisissent, par exemple de reproduire et les échecs fix
    • mon serveur CI devrait fonctionner après avoir exécuté avec succès les tests unitaires

Cela semble être un scénario typique. À l'heure actuelle, je suis en cours d'exécution:

  • les tests unitaires dans la phase "test"
  • les tests d'acceptation dans la phase "vérifier"

Il y a deux emplois de CI configurés, les deux pointant vers la branche VCS du projet:

  1. "Commit étape", qui va "mvn package" (compilation et le test du code de l'unité, construire l'artefact), qui si elle réussit, déclencheurs:
  2. "Les tests automatisés d'acceptation", qui va "MVN vérifier" (mis en place, course et démontage des tests d'acceptation)

Le problème est que les tests unitaires travail 2 et construit l'artefact sous test tout recommencer (car l'appelle automatiquement la phase de package phase de vérification). Ceci est indésirable pour plusieurs raisons (importance décroissante):

  • l'artefact créé par l'emploi 2 pourrait ne pas être identique à celui créé par l'emploi 1 (par exemple s'il y a eu un commit dans l'intervalle)
  • allonge la boucle de rétroaction au développeur qui a fait la commettras (à savoir prend plus de temps pour eux de savoir qu'ils ont cassé la construction)
  • gaspille les ressources sur le serveur CI

Alors, ma question est, comment puis-je configurer travail 2 pour utiliser l'artefact créé par l'emploi 1?

Je me rends compte que je pouvais avoir un emploi CI qui fonctionne « MVN vérifier », qui créeraient l'artefact qu'une seule fois, mais je veux avoir les emplois de CI distincts décrits ci-dessus afin de mettre en œuvre un déploiement de style Farley pipeline.


Dans le cas où il aide tout le monde, voici la pleine Maven 2 POM de « projet 2 » dans la réponse acceptée:

<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>

Notez que même si ce projet « tests » ne crée pas un artefact, il doit utiliser une sorte d'emballage (je « pot » ici), sinon aucun test sont exécutés dans la phase de vérification.

Était-ce utile?

La solution

Essayez deux projets Maven. Le premier contient la construction et les tests unitaires. Vous installez les objets dans votre référentiel local. Le deuxième travail exécute le deuxième projet Maven qui déclare les objets du premier projet en tant que dépendances et exécute les tests fonctionnels.

Je ne sais pas si le scénario que je viens de décrire est possible, mais je pense qu'il est.

Pour une amélioration rapide, vous pouvez contourner le test unitaire avec -Dmaven.test.skip=true. Si vous passez le numéro de révision de votre code dans votre scm au deuxième emploi, vous devriez être en mesure de la caisse le même code source.

Vous pouvez également vérifier dans le plug-in Clone Espace de travail SCM. Cela pourrait vous offrir quelques options supplémentaires.

Autres conseils

Je sais que ça fait longtemps, mais cela est bien indexé et aucune des réponses ne m'a demandé ce, mais j'ai trouvé quelque chose qui fonctionne:

mvn failsafe:integration-test

exécute les tests directement, sans passer par toutes les étapes intermédiaires de la construction du projet. Vous pouvez ajouter failsafe:verify après.

  

Alors, ma question est, comment puis-je configurer   Emploi 2 à utiliser l'artefact créé par   1 emploi?

Vous ne pouvez pas.

Vous n'avez pas besoin. cycle de vie Maven Build est configuré de manière que les sons comme elle répondra à vos besoins. Le cycle de vie de test ne fonctionnera que les junits rapides. Forfait construire votre état final sans courir la vérification.

Vous avez seulement besoin d'un emploi de CI. Lorsque le CI exécute votre Deploy Maven / install cycle de vie, si les junits échouent la génération échoue, les scripts de vérification ne seront pas exécutés.

Vous pouvez définir un profil Maven qui sera utilisé pour exécuter uniquement les tests d'intégration. Je le fais beaucoup.

Quelque chose comme ceci:

<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>

Vous invoquerait cela avec:

mvn verify -Pintegration

Malheureusement, le plugin WAR ne peut pas être ignorée, mais vous pouvez envoyer sa sortie à un endroit de la route (je l'ai utilisé / tmp). Si vous voulez vraiment économiser de millisecondes, vous pouvez aussi faire ignorer les ressources Web (sauf web.xml, il ne fonctionnera pas sans cela).

Vous pouvez également utiliser le profil pour ignorer tous les autres plug-ins que vous pourriez exécuter, par exemple le plug-in d'assemblage, Cobertura, PMD, etc.

profil Maven qui exécute uniquement les tests d'intégration ( comme suggéré ici ) ne suffit pas. Vous devez également vous assurer que la configuration de maven-compilateur-plugin useIncrementalCompilation = false . L'exécution du profil de cette façon, ne sera pas automatiquement recompiler, par exemple:.

<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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top