J'ai une application Web qui fournit un service Web. Je souhaite effectuer des tests JUnit avec SoapUI pour vérifier si ce service fonctionne correctement.
Mais pour tester une application de service Web doit être déployée sur mon serveur Tomcat 7.
Je ne sais pas comment configurer maven pour construire war, puis le déployer sur Tomcat (idéalement: pour exécuter une instance distincte de Tomcat à cet effet), puis pour exécuter des tests JUnit.
.__ J'apprécierai toute aide.
J'utilise Maven 2.2.1
Il existe un certain nombre d'écoles de pensée sur la manière de gérer ce type de test d'intégration avec Maven.
Je tiens à souligner que lorsque vous déployez une application sur un serveur d'applications, vous n'êtes plus dans le domaine du test unitaire. Étant donné que l'application entière est déployée dans un conteneur, vous testez l'intégration de ces deux composants.
Maintenant, il n’ya rien de mal à utiliser JUnit pour exécuter tests d’intégration} (bien qu’il y ait certaines limitations que vous pouvez rencontrer, par exemple tests unitaires ne devrait pas s’occuper de la séquence de tests individuels - en supposant vous les écrivez correctement - donc JUnit applique ceci en ne garantissant aucune séquence d'exécution ... avant Java 1.7, l'ordre d'exécution était accidentellement impliqué par l'ordre des méthodes de test dans une classe, mais ce n'était pas le cas. fait partie du contrat JUnit ... Certaines personnes passent à d'autres frameworks de test pour leurs tests intégration, par exemple TestNG, si elles trouvent le focus de test unitaire de JUnit gênant leur développement de test)
Il convient de garder à l'esprit que le cycle de vie Maven utilise la phase test
pour l'exécution des tests unit.
En ce qui concerne les intégration tests, il existe deux écoles de pensée (et demi) sur la bonne façon de gérer les tests avec Maven.
integration-test/verify
Cette école de pensée utilise les phases après package
pour démarrer un conteneur, exécuter les tests d'intégration, démonter le conteneur et enfin vérifier les résultats des tests et échouer lors de la construction en cas d'échec des tests.
NE JAMAIS JAMAIS EXÉCUTER mvn integration-test
car cela ne démontera pas le conteneur correctement, chaque fois que vous pensez taper mvn integration-test
, vous voulez taper mvn verify
(oh look, il est plus facile et plus rapide de taper aussi ... bonus)
Donc, avec cela, vous procédez comme suit:
pre-integration-test
avec fork
=true
integration-test
post-integration-test
verify
.Pour des points supplémentaires, utilisez build-helper-maven-plugin: reserve-network-port lié à la phase validate
pour vous assurer que le serveur de test est démarré sur un port réseau inutilisé, puis utilisez le filtrage des ressources en fonction de la testez les ressources pour transmettre le port aux tests ou utilisez une propriété système transmise par systemPropertyVariables pour que le numéro de port soit disponible pour les tests.
run-its
) si les tests sont trop lents pour exécuter chaque génération.IT
et bien que Maven sache exécuter des tests commençant/finissant avec Test
avec Surefire et des tests commençant/finissant avec IT
avec Failsafe, votre IDE ne le fait probablement pas. De plus, votre IDE ne va pas démarrer le conteneur pour vous, vous devez donc effectuer beaucoup de travail à la main pour exécuter les tests manuellement. Le débogage des tests nécessite potentiellement la connexion de deux débogueurs, par exemple. un pour déboguer l'application en cours d'exécution dans un conteneur et l'autre pour déboguer les cas de test .
mvnDebug -Dmaven.failsafe.debug=true verify
Associe vos tests au processus de construction Maven.
Cette école de pensée déplace les tests d'intégration dans un module distinct qui dépend du module war
et copie la war
dans les ressources de test à l'aide, par exemple, de dependency:copy-dependencies
lié à la phase generate-test-resources
couplé à une dépendance Tomcat7 à tester.
Les cas de test démarrent le conteneur Tomcat7 en utilisant mode incorporé
war
n'est reconstruit que si vous dépassez la phase package
. Par conséquent, vous devez exécuter au moins mvn clean package
périodiquement pour actualiser le code sous test lors de l'utilisation de l'EDI.war
. Vous pouvez donc libérer un artefact war
cassé puis faire échouer la construction du réacteur pour le module de test d'intégration. Certaines personnes s'opposent à ce problème en disposant le module de test d'intégration dans src/it
et en utilisant Maven Invoker Plugin pour exécuter les tests ... bien que cela fournisse une intégration plus médiocre IDE, je ne recommande donc pas cette ligne.C'est une sorte d'hybride des deux approches.Vous utilisez Failsafe pour exécuter les tests, mais ces derniers sont responsables du démarrage et de l'arrêt du conteneur Tomcat7 dans lequel vous souhaitez effectuer le test.
Avantages.
I hope the above helps you understand the options you have. There may be other tweaks but in general the above are considered the best practice(s) for integration testing with Maven at present.
@Stephen Connolly - votre réponse ci-dessus était vraiment bonne. Je pensais que je mettrais en marche et montrerais une configuration complète pour ce que vous avez appelé une réponse School 1
.
Cette configuration:
@Category
sur les classes racine étendues par les tests unitaires et les tests d'intégration.Il y a d'autres choses ici comme comment définir certaines propriétés du système sur l'application dépendante uniquement.
Jusqu'à présent, cette configuration fonctionne à merveille ..
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>reserve-network-port</id>
<goals>
<goal>reserve-network-port</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<portNames>
<portName>Tomcat.maven.http.port</portName>
</portNames>
</configuration>
</execution>
<execution>
<id>get-local-ip</id>
<goals>
<goal>local-ip</goal>
</goals>
<configuration>
<!-- if not given, 'local.ip' name is used -->
<localIpProperty>local.ip</localIpProperty>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.Apache.Tomcat.maven</groupId>
<artifactId>Tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- http port from reserve-network-port-plugin-->
<port>${Tomcat.maven.http.port}</port>
<!-- application path always starts with /-->
<path>/</path>
<webapps>
<webapp>
<groupId>com.company.other.app</groupId>
<artifactId>web-rest</artifactId>
<version>1.0.1-SNAPSHOT</version>
<type>war</type>
<contextPath>/webapi-loopback</contextPath>
<asWebapp>true</asWebapp>
</webapp>
</webapps>
</configuration>
<executions>
<execution>
<id>start-server</id>
<configuration>
<fork>true</fork>
<skip>${skipTests}</skip>
<systemProperties>
<spring.profiles.active>test,h2</spring.profiles.active>
</systemProperties>
</configuration>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>stop-server</id>
<configuration>
<skip>${skipTests}</skip>
</configuration>
<phase>post-integration-test</phase>
<goals>
<goal>shutdown</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<excludedGroups>com.company.app.service.IntegrationTestRootClassAnnotatedWithAtCategory</excludedGroups>
</configuration>
<executions>
<execution>
<id>unit-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<argLine>-Xmx1024m -XX:MaxPermSize=256m @{jacocoArgLine}</argLine>
<excludedGroups> com.company.app.service.IntegrationTestRootClassAnnotatedWithAtCategory </excludedGroups>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18</version>
<dependencies>
<dependency>
<groupId>org.Apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.18</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>start-integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<argLine>-Xmx1024m -XX:MaxPermSize=256m @{jacocoArgLine}</argLine>
<groups>com.company.app.IntegrationTestRootClassAnnotatedWithAtCategory</groups>
<includes>
<include>**/*.Java</include>
</includes>
<systemPropertyVariables>
<program.service.url>
http://${local.ip}:${Tomcat.maven.http.port}/webapi-loopback
</program.service.url>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Comme Stephen Connolly l'explique, il n'existe pas de moyen direct de configurer cela. Je vais vous expliquer comment résoudre ce problème en utilisant le plug-in Failsafe. Dans le cycle de vie Maven, le type de test peut être testé. L'unité de test l'un d'eux et un autre est le test d'intégration. Les tests unitaires peuvent être exécutés à l'étape du test du cycle de vie de maven. Lorsque vous souhaitez effectuer un test d’intégration, vous pouvez le faire en phase de vérification. Si vous voulez connaître la différence entre les tests unitaires et les tests intégrés, il s'agit d'un bon . Par défaut, les classes de tests unitaires doivent être au format ***/*Test.Java
et **/*TestCase.Java
de ce format. Le plug-in à sécurité intégrée recherchera **/IT*.Java
, **/*IT.Java
et **/*ITCase.Java
.
Ici, j'ai une classe de test unitaire et une classe de test intégrée. Maintenant, je vais expliquer, à quoi devrait ressembler le look de maven pom.xml. La section de construction de la configuration maven devrait ressembler à ceci.
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
<warName>${name}</warName>
<outputDirectory>/home/jobs/wso2/wso2as-5.3.0/repository/deployment/server/webapps</outputDirectory>
<goal>
</goal>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12.4</version>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Les tests unitaires sont exécutés avant le déploiement de l'application Web (fichier war). Mais les tests intégrés sont exécutés en phase de vérification. J'espère que votre exigence est satisfaite à cette étape.