Запуск сервера баз данных H2 с Maven? - PullRequest
36 голосов
/ 05 февраля 2010

Предположим, я хочу создать и использовать базу данных H2 для своих интеграционных тестов.

Maven имеет команду для запуска тестов: mvn test.

Есть ли способ указать maven запустить сервер базы данных H2 для тестов и остановить его, когда он будет завершен?

Я представляю, как это работает, подобно тому, как я могу запустить tomcat с помощью команды Maven (mvn tomcat:run).

Извините, если этот вопрос не имеет смысла, я все еще думаю о новых понятиях.

Ответы [ 9 ]

18 голосов
/ 08 февраля 2010

Мне удалось заставить его работать без использования внешнего сервера, просто добавив зависимость к H2 через Maven, а затем с помощью этого компонента:

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

Опять же, это потребовало, чтобы я использовал файловую БД вместо оперативной памяти. Но это делает свое дело.

12 голосов
/ 05 февраля 2010

вы можете создать 2 небольших класса с основными методами, которые запускают и останавливают базу данных. Идея состоит в том, чтобы запустить класс StartServer до запуска интеграционных тестов, а затем класс StopServer после запуска тестов.

вы должны сделать то же самое для вашего сервера БД, как описано где-то в этом документе (описание для запуска и остановки Jetty в интеграционных тестах)

в вашем pom.xml вы должны определить maven-exec-plugin для запуска цели exec: java и создать 2 выполнения (1 для вызова StartServer и 1 для 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>

надеюсь, это то, что вы хотите

8 голосов
/ 19 апреля 2013

Этот плагин отлично работает для создания новой базы данных H2 в режиме tcp перед интеграционными тестами (фаза плагина по умолчанию): h2-maven-plugin на github

Это плохо документировано, но вы можете проверить источники Mojo, чтобы узнать параметры конфигурации. Опубликовано на Maven Central.


В основном, для интеграционных тестов вы можете захотеть, чтобы Maven:

  • Зарезервируйте произвольно доступные сетевые порты для сервера Tomcat и H2 (во избежание конфликтов портов)
  • Запустить сервер H2
  • Запустить сервер Tomcat
  • Запуск интеграционных тестов
  • Остановите сервер Tomcat
  • Остановить сервер H2

Этого можно достичь с помощью конфигурации Maven, которая выглядит следующим образом. При условии, что ваши интеграционные тесты помечены с помощью пользовательского интерфейса JUnit Категория:

@Category(IntegrationTest.class)

Эта конфигурация Maven прекрасно работает для меня:

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

Возможно, вы захотите использовать фильтры maven в файле контекста tomcat для замены порта:

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

С содержанием файла:

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

Или, если вам не нужен источник данных JNDI, вы можете использовать объявленный Spring источник данных, используя то же свойство ...


Одна дополнительная поездка, если вы хотите иметь возможность настроить интеграционные тесты Tomcat и запустить интеграционные тесты из вашей IDE:

Вы можете использовать свойство для форка или без сервера Tomcat:

<fork>${integrationTestsForkTomcatJvm}</fork>

Когда вы установите fork = false, сервер заблокируется, и maven не будет продолжаться, поэтому интеграционные тесты не будут запускаться, но вы сможете запускать их из своего ide.

5 голосов
/ 24 февраля 2011

Я только что начал проект для плагина H2 для maven @ bitbucket. Я буду признателен за любую помощь с этим.

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

Надеюсь, это будет полезно.

4 голосов
/ 17 апреля 2013

Я создаю базу данных H2 на основе файлов до запуска модульных тестов. Файл находится в каталоге target и может быть удален в любое время с помощью mvn clean.

Я использую maven-sql-plugin следующим образом:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>sql-maven-plugin</artifactId>
  <version>1.5</version>
  <dependencies>
    <dependency>
      <groupId>com.h2database</groupId>
      <artifactId>h2</artifactId> 
      <version>1.3.166</version>
    </dependency>
  </dependencies>
  <configuration>
    <driver>org.h2.Driver</driver>
    <url>jdbc:h2:file:target/db/testdb</url>
    <username>sa</username>
    <password></password>
    <autocommit>true</autocommit>
    <skip>${maven.test.skip}</skip>
  </configuration>
  <executions>
    <execution>
      <id>create-db</id>
      <phase>process-test-resources</phase>
      <goals>
        <goal>execute</goal>
      </goals>
      <configuration>
        <srcFiles>
          <srcFile>${sql.dir}/drop_db.sql</srcFile>
          <srcFile>${sql.dir}/tables.sql</srcFile>
          <srcFile>${sql.dir}/constraints.sql</srcFile>
          ... etc ...
        </srcFiles>
      </configuration>
    </execution>
  </executions>
</plugin>

Базу данных можно создать, запустив mvn process-test-resources. Когда тесты будут запущены, убедитесь, что вы подключаетесь к базе данных в target/db/testdb через свойства гибернации.

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
      destroy-method="close"
      p:driverClassName="org.h2.Driver"
      p:url="jdbc:h2:file:target/db/testdb"
      p:username="sa"
      p:password="" />

Вам также понадобится зависимость от com.h2database.h2 в зависимостях maven.

4 голосов
/ 05 февраля 2010

В моем проекте для модульного тестирования я попросил Spring обработать создание и инициализацию базы данных. Как указано в документации H2 , для этого можно создать компонент:

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

Вам просто нужно запустить контекст Spring с этой конфигурацией при запуске модульных тестов.

3 голосов
/ 01 декабря 2011

Если вы хотите сделать это в памяти, просто используйте другой URL:

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

Вы можете указать дополнительные параметры, такие как:; DB_CLOSE_DELAY = -1

см .: http://www.h2database.com/html/features.html#in_memory_databases

1 голос
/ 08 апреля 2014

следующее делает за меня работу (просто используя h2 зависимость и exec-maven-plugin):

    <build>
        <plugins>
            <!-- start/stop H2 DB as a server -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <executions>
                    <execution>
                        <id>start-h2</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>java</goal>
                        </goals>
                        <configuration>
                            <mainClass>org.h2.tools.Server</mainClass>
                            <arguments>
                                <argument>-tcp</argument>
                                <argument>-tcpDaemon</argument>
                            </arguments>
                        </configuration>
                    </execution>
                    <execution>
                        <id>stop-h2</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>java</goal>
                        </goals>
                        <configuration>
                            <mainClass>org.h2.tools.Server</mainClass>
                            <arguments>
                                <argument>-tcpShutdown</argument>
                                <argument>tcp://localhost:9092</argument>
                            </arguments>
                        </configuration>
                    </execution>
                </executions>
                <configuration>
                    <includeProjectDependencies>true</includeProjectDependencies>
                    <includePluginDependencies>true</includePluginDependencies>
                    <executableDependency>
                        <groupId>com.h2database</groupId>
                        <artifactId>h2</artifactId>
                    </executableDependency>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>com.h2database</groupId>
                        <artifactId>h2</artifactId>
                        <version>1.3.173</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
</build>

обратите внимание, в моем pom.xml com.h2database:h2 не было зависимости проекта. В случае, если он у вас есть, вам не нужно явно называть его зависимостью плагина.

1 голос
/ 05 февраля 2010

Поскольку H2 не предоставляет плагин Maven, вы должны запустить его с помощью maven-antrun-plugin. Напишите код для запуска и остановки двигателя h2 в задаче ant и вызывайте его, когда ваш тест интеграции запускается и останавливается.

Подробнее см. http://docs.codehaus.org/display/MAVENUSER/Maven+and+Integration+Testing

...