web-dev-qa-db-fra.com

Ignorer les tests dans certains modules de Maven

J'aimerais que mes builds Maven exécutent la plupart des tests unitaires. Mais il y a des tests unitaires dans un projet qui sont plus lents et j'aimerais généralement les exclure; et parfois allumez-les.

Question : Comment dois-je procéder?

Je connais -Dmaven.test.skip=true, mais cela désactive tous les tests unitaires.

Je sais également ignorer les tests d'intégration, décrits ici . Mais je n'ai pas de tests d'intégration, juste des tests unitaires, et je n'ai pas d'appels explicites au plugin maven-surefire. (J'utilise Maven 2 avec le plugin Eclipse-Maven).

64
Joshua Fox

Qu'en est-il des sauts de tests uniquement dans ce module?

Dans le pom.xml de ce module:

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.Apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.4.2</version>
        <configuration>
          <skipTests>true</skipTests>
        </configuration>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

Finalement, vous pouvez créer un profil qui désactivera les tests (toujours le pom.xml du module):

<project>
  [...]
  <profiles>
    <profile>
      <id>noTest</id>
      <activation>
        <property>
          <name>noTest</name>
          <value>true</value>
        </property>
      </activation>
      <build>
        <plugins>
          <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.4.2</version>
            <configuration>
              <skipTests>true</skipTests>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
  [...]
</project>

Avec cette dernière solution, si vous exécutez mvn clean package, il exécutera tous les tests. Si vous exécutez mvn clean package -DnoTest=true, il n'exécutera pas les tests de ce module.

75
Romain Linsolas

Je pense que c'est plus facile, et a également l'avantage de travailler pour des tests non infaillibles (dans mon cas, FlexUnitTests)

<profile>
   <id>noTest</id>
    <properties>
       <maven.test.skip>true</maven.test.skip>
    </properties>
 </profile>

Si vous avez un grand projet multi-modules et que vous souhaitez ignorer les tests uniquement dans certains modules sans avoir besoin de modifier chacun des modules pom.xml fichier avec configuration et profilage personnalisés, vous pouvez ajouter ce qui suit au parent pom.xml fichier:

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
            <version>1.12</version>
            <executions>
                <execution>
                    <id>regex-property</id>
                    <goals>
                        <goal>regex-property</goal>
                    </goals>
                    <configuration>
                        <name>maven.test.skip</name>
                        <value>${project.artifactId}</value>
                        <regex>(module1)|(module3)</regex>
                        <replacement>true</replacement>
                        <failIfNoMatch>false</failIfNoMatch>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
<modules>
    <module>module1</module>
    <module>module2</module>
    <module>module3</module>
</modules>

Grace à build-helper-maven-plugin vous vérifieriez en fait dynamiquement si vous êtes dans un certain module ou non pendant la construction, via le project.artifactId propriété (pointant vers chaque module artifactId lors de la construction), l'expression régulière recherchait alors la correspondance pour certaines valeurs (les noms de modules pour lesquels vous souhaitez ignorer les tests) et remplissait le maven.test.skip en conséquence (en la définissant sur true).

Dans ce cas, les tests seront ignorés pour module1 et module3 tout en fonctionnant correctement pour module2, c'est-à-dire exprimé par l'expression régulière.

L'avantage de cette approche est de la rendre dynamique et centralisée (dans le parent pom.xml) donc mieux pour la maintenance: vous pouvez ajouter ou supprimer des modules à tout moment en changeant simplement l'expression régulière ci-dessus.

Évidemment, si ce n'est pas le comportement par défaut de la construction (cas recommandé), vous pouvez toujours envelopper l'extrait ci-dessus dans un profil maven .


Vous pouvez également aller plus loin et avoir un comportement dynamique en fonction de votre saisie:

<properties>
    <test.regex>none</test.regex>
</properties>

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
            <version>1.12</version>
            <executions>
                <execution>
                    <id>regex-property</id>
                    <goals>
                        <goal>regex-property</goal>
                    </goals>
                    <configuration>
                        <name>maven.test.skip</name>
                        <value>${project.artifactId}</value>
                        <regex>${test.regex}</regex>
                        <replacement>true</replacement>
                        <failIfNoMatch>false</failIfNoMatch>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Ici, nous remplaçons en fait la valeur regex par une propriété, test.regex, avec une valeur par défaut à none (ou tout ce qui ne correspondrait à aucun nom de module ou, également, aux correspondances par défaut requises).

Ensuite, à partir de la ligne de commande, nous pourrions avoir

mvn clean test -Dtest.regex="(module1)" > will skip tests only for module1
mvn clean test -Dtest.regex="(module1)|(module2)" > will skip tests on module1 and module2
mvn clean test -Dtest.regex="(module1)|(module2)|(module3)" > will skip the three module tests
mvn clean test -Dtest.regex=".+" > will skip all module tests
mvn clean test > would not skip anything (or fall back on default behavior)

Autrement dit, au moment de l'exécution, vous décidez, sans avoir besoin de modifier le pom.xml fichier ou activation d'un profil.

5
A_Di-Matteo

En utilisant Surefire Plugin 2.19, vous pouvez simplement exclure les tests que vous ne souhaitez pas utiliser d'expressions régulières:

mvn '-Dtest=!%regex[.*excludedString.*]' test

La commande ci-dessus exclura tous les tests qui contiennent exclusString.

NB1 Si un guillemet double (") est utilisé à la place de l'apostrophe ('), la commande ne sera pas interprétée correctement et produira des résultats inattendus. (Testé avec bash 3.2.57)

NB2 Une attention particulière doit être accordée aux projets dans lesquels plusieurs versions du plugin surefire sont utilisées. Les versions de surefire antérieures à 2.19 n'exécuteront aucun test car elles ne prennent pas en charge les expressions régulières.

Gestion des versions (il peut être judicieux d'ajouter ceci dans le fichier pom parent):

<build>
  <pluginManagement>
    <plugins>
      <plugin>
        <groupId>org.Apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.19.1</version>
      </plugin>
    </plugins>
  </pluginManagement>
</build>

Exemples de commandes de construction qui sautent les tests: https://artbcode.wordpress.com/2016/11/28/how-to-skip-a-subset-of-the-unit-tests/

2
artBCode

J'avais un besoin légèrement différent de cette question qui peut s'avérer utile. Je voulais exclure de la ligne de commande quelques tests différents de différents packages, donc un seul caractère générique ne le ferait pas.

J'ai trouvé dans les règles de documentation Maven Failsafe pour les exclusions que vous pouvez spécifier une liste séparée par des virgules d'exclusions regex ou génériques: https://maven.Apache.org/surefire/maven-failsafe-plugin/examples/ inclusion-exclusion.html

Donc, mon pomfile ressemblait à ceci:

<excludes>
    <exclude>${exclude.slow.tests}</exclude>
</excludes>

et ma ligne de commande comprenait ceci:

mvn install "-Dexclude.slow.tests=**/SlowTest1.Java, **/package/ofslowtests/*.Java, **/OtherSlowTest.Java"

Pour moi, l'ingrédient clé consistait à obtenir un tas de tests dans une propriété maven dans une seule instruction d'exclusion.

2
Austin