37 votes

Démarrage d'un serveur de base de données H2 à partir de Maven?

Supposons que je veuille créer et utiliser une base de données H2 pour mes tests d'intégration.

Maven a une commande pour exécuter des tests: mvn test .

Existe-t-il un moyen de dire à maven de démarrer un serveur de base de données H2 pour les tests et de l'arrêter une fois terminé?

J'imagine que cela fonctionne de la même manière que je peux exécuter tomcat via une commande Maven ( mvn tomcat:run ).

Désolé si cette question est absurde, je suis toujours en train de tourner la tête autour de nouveaux concepts.

19voto

roufamatic Points 6773

J'ai pu le faire fonctionner sans utiliser de serveur externe simplement en ajoutant la dépendance à H2 via Maven puis en utilisant ce bean:

 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.h2.Driver"/>
    <property name="url" value="jdbc:h2:file:h2\db"/>
    <property name="username" value="sa"/>
    <property name="password" value=""/>        
</bean>
 

Là encore, cela exigeait que j'utilise une base de données basée sur des fichiers au lieu de la mémoire. Mais ça fait l'affaire.

12voto

Stefan De Boey Points 1656

vous pouvez créer 2 classes de petite taille avec les principales méthodes de démarrage et d'arrêt de la base de données. l'idée est de lancer la StartServer de classe avant les tests d'intégration sont gérés et puis la classe StopServer après les tests sont exécutés.

vous devriez faire la même chose pour votre serveur de base de données comme décrit dans ce document (description est pour le démarrage et l'arrêt de la Jetée dans les tests d'intégration)

dans votre pom.xml vous devez définir le maven-exec-plugin pour exécuter l' exec:java objectif et de créer 2 exécutions (1 pour l'appel de StartServer et 1 pour StopServer):

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>1.1.1</version>
  <executions>
    <execution>
      <!-- start server before integration tests -->
      <id>start</id>
      <phase>pre-integration-test</phase>
      <goals>
        <goal>java</goal>
      </goals>
      <configuration>
        <mainClass>com.foo.StartServer</mainClass>
      </configuration>
     </execution>
     <execution>
      <!-- stop server after integration tests -->
      <id>stop</id>
      <phase>post-integration-test</phase>
      <goals>
        <goal>java</goal>
      </goals>
      <configuration>
        <mainClass>com.foo.StopServer</mainClass>
      </configuration>
     </execution>
   </executions>
 </plugin>

j'espère que c'est ce que vous voulez

8voto

Sebastien Lorber Points 9682

Ce plugin fonctionne très bien lancer un nouveau H2 DB en mode tcp avant les tests d'intégration (le plugin par défaut de phase): h2-maven-plugin sur github

Il n'est pas bien documentée mais vous pouvez vérifier l'Mojo sources pour connaître les options de configuration. Il est publié sur maven central.


En gros, pour les tests d'intégration, vous pouvez Maven:

  • Réserve au hasard la disposition de ports réseau, pour votre serveur Tomcat, et votre H2 (pour éviter les conflits de ports)
  • Démarrer le H2 serveur
  • Démarrer le serveur Tomcat
  • Exécuter les tests d'intégration
  • Arrêter le serveur Tomcat
  • Arrêter le H2 serveur

Ceci peut être réalisé avec un Maven configuration qui ressemble à ceci. En supposant que vos tests d'intégration sont annotée avec une interface personnalisée JUnit Catégorie:

@Category(IntegrationTest.class)

Cette Maven configuration fonctionne très bien pour moi:

<profile>
   <id>it</id>
   <build>
     <plugins>

       <!-- Reserve randomly available network ports -->
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>build-helper-maven-plugin</artifactId>
         <executions>
           <execution>
             <id>reserve-network-port</id>
             <goals>
               <goal>reserve-network-port</goal>
             </goals>
             <phase>process-resources</phase>
             <configuration>
               <portNames>
                 <portName>tomcat.test.http.port</portName>
                 <portName>h2.test.tcp.port</portName>
               </portNames>
             </configuration>
           </execution>
         </executions>
       </plugin>


       <!-- Start H2 before integration tests, accepting tcp connections on the randomly selected port -->
       <plugin>
         <groupId>com.edugility</groupId>
         <artifactId>h2-maven-plugin</artifactId>
         <version>1.0</version>
         <configuration>
           <port>${h2.test.tcp.port}</port>
         </configuration>
         <executions>
             <execution>
               <id>Spawn a new H2 TCP server</id>
               <goals>
                 <goal>spawn</goal>
               </goals>
             </execution>
             <execution>
               <id>Stop a spawned H2 TCP server</id>
               <goals>
                 <goal>stop</goal>
               </goals>
             </execution>
           </executions>
       </plugin>


       <!-- Start Tomcat before integration tests on the -->
       <plugin>
         <groupId>org.apache.tomcat.maven</groupId>
         <artifactId>tomcat7-maven-plugin</artifactId>
         <configuration>
           <systemProperties>
             <spring.profiles.active>integration_tests</spring.profiles.active>
             <httpPort>${http.test.http.port}</httpPort>
             <h2Port>${h2.test.tcp.port}</h2Port>
           </systemProperties>
           <port>${http.test.http.port}</port>
           <contextFile>src/main/java/META-INF/tomcat/webapp-test-context-using-h2.xml</contextFile>
           <fork>true</fork>
         </configuration>
         <executions>
           <execution>
             <id>run-tomcat</id>
             <phase>pre-integration-test</phase>
             <goals>
               <goal>run</goal>
             </goals>
           </execution>
           <execution>
             <id>stop-tomcat</id>
             <phase>post-integration-test</phase>
             <goals>
               <goal>shutdown</goal>
             </goals>
           </execution>
         </executions>
         <dependencies>
           <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <version>${mysql.version}</version>
           </dependency>
           <dependency>
             <groupId>com.h2database</groupId>
             <artifactId>h2</artifactId>
             <version>${h2.version}</version>
           </dependency>
         </dependencies>
       </plugin>


       <!-- Run the integration tests annotated with @Category(IntegrationTest.class) -->
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-failsafe-plugin</artifactId>
         <!-- Bug in 2.12.x -->
         <version>2.11</version>
         <dependencies>
           <dependency>
             <groupId>org.apache.maven.surefire</groupId>
             <artifactId>surefire-junit47</artifactId>
             <version>2.12.4</version>
           </dependency>
         </dependencies>
         <configuration>
           <groups>com.mycompany.junit.IntegrationTest</groups>
           <failIfNoTests>false</failIfNoTests>
           <junitArtifactName>junit:junit-dep</junitArtifactName>
           <systemPropertyVariables>
             <httpPort>${tomcat.test.http.port}</httpPort>
             <h2Port>${h2.test.tcp.port}</h2Port>
           </systemPropertyVariables>
         </configuration>
         <executions>
           <execution>
             <goals>
               <goal>integration-test</goal>
             </goals>
           </execution>
         </executions>
       </plugin>

     </plugins>
   </build>
 </profile>

Vous souhaiterez peut-être utiliser maven filtres sur le tomcat fichier de contexte, de sorte que le port est remplacée:

   <contextFile>src/main/java/META-INF/tomcat/webapp-test-context-using-h2.xml</contextFile>

Avec le contenu du fichier en cours:

  <Resource name="jdbc/dataSource"
            auth="Container"
            type="javax.sql.DataSource"
            maxActive="100"
            maxIdle="30"
            maxWait="10000"
            username=""
            password=""
            driverClassName="org.h2.Driver"
            url="jdbc:h2:tcp://localhost:${h2.test.tcp.port}/mem:db;DB_CLOSE_ON_EXIT=FALSE;MODE=MySQL"/>

Ou si vous ne voulez pas d'une datasource JNDI, vous pouvez utiliser un Ressort a déclaré la source de données, en utilisant la même propriété...


Un voyage supplémentaire si vous voulez être en mesure de configurer vos tests d'intégration de tomcat, et exécuter les tests d'intégration de l'IDE:

Vous pouvez utiliser une propriété de la fourche à la fourchette ou non le serveur Tomcat:

<fork>${integrationTestsForkTomcatJvm}</fork>

Lorsque vous définissez la fourche=false, le serveur se bloque et maven ne vais pas continuer, donc les tests d'intégration ne sera pas exécuté, mais vous serez en mesure de les exécuter à partir de votre ide.

5voto

Ruslan Pilin Points 51

Je viens de commencer le projet de plugin H2 pour maven @ bitbucket. J'apprécierai toute aide avec elle.

https://bitbucket.org/dohque/maven-h2-plugin

J'espère que ce sera utile.

4voto

romaintaz Points 32120

Dans mon projet, pour les tests unitaires, j'ai demandé à Spring de gérer la création et l'initialisation de cette base de données. Comme indiqué dans la documentation H2 , vous pouvez créer un bean pour cela:

 <bean id = "org.h2.tools.Server"
    class="org.h2.tools.Server"
    factory-method="createTcpServer"
    init-method="start"
    destroy-method="stop">
    <constructor-arg value="-tcp,-tcpAllowOthers,true,-tcpPort,8043" />
</bean>
 

Il vous suffit de démarrer le contexte Spring avec cette configuration lorsque vous démarrez vos tests unitaires.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X