Starten eines H2 Database Server von Maven?
Frage
Angenommen, ich möchte eine H2-Datenbank für meine Integrationstests erstellen und zu verwenden.
Maven hat einen Befehl auszuführen Tests. mvn test
Gibt es eine Möglichkeit Maven zu sagen, einen H2-Datenbankserver für die Tests zu starten und stoppen, wenn es fertig ist?
Ich stelle mir diese Arbeit ähnlich, wie ich Kater über einen Maven Befehl ausführen kann (mvn tomcat:run
).
Sorry, wenn diese Frage unsinnig ist, ich bin Einwickeln noch meinen Kopf um neue Konzepte.
Lösung
Ich war in der Lage, es zu erhalten, ohne über einen externen Server zu arbeiten, nur um die Abhängigkeit zu H2 über Maven Hinzufügen und dann mit dieser 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>
Dann wieder, das erforderlich ist, dass ich eine dateibasierte DB statt im Arbeitsspeicher verwenden. Aber es funktioniert der Trick.
Andere Tipps
Sie können zwei kleine Klassen mit den wichtigsten Methoden erstellen, die die Datenbank starten und stoppen. die Idee ist, die Startserver-Klasse, bevor die Integrationstests laufen und dann Klasse Stopserver, nachdem die Tests laufen zu laufen.
Sie sollten das gleiche für Ihren DB-Server tun als rel="noreferrer"> dies irgendwo in (Beschreibung ist zum Starten und Stoppen Jetty in Integrationstests)
in Ihrem pom.xml sollten Sie die Maven-Exec-Plugin definieren das exec: java Ziel und schaffen zwei Ausführungen (1 für Startserver und 1 für Stopserver Aufruf):
<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>
hoffe, das ist, was Sie wollen
Dieses Plugin funktioniert eine neue H2 DB mit tcp-Modus vor Integrationstests (der Standard-Plug-Phase) zum Laichen: h2-maven-Plugin auf github
Es ist nicht gut dokumentiert, aber Sie können die Mojo Quellen überprüfen, um die Konfigurationsoptionen kennen. Es ist auf Maven zentralen veröffentlicht.
Im Grunde genommen für Integrationstests, können Sie Maven wollen:
- Reserve zufällig verfügbarer Netzwerk-Ports, für Ihren Tomcat-Server und Ihrem H2 (Portkonflikte zu vermeiden)
- Starten Sie den H2-Server
- Starten Sie den Tomcat-Server
- Ausführen Integrationstests
- Stoppen Sie den Tomcat-Server
- Stoppen Sie den H2-Server
Dies kann mit einer Maven-Konfiguration wie folgt aussehen erreicht werden. Angenommen werden Ihre Integrationstests mit einer benutzerdefinierten Schnittstelle JUnit Kategorie annoted:
@Category(IntegrationTest.class)
Die Maven-Konfiguration funktioniert gut für mich:
<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>
Sie möchten Maven Filter auf der tomcat Kontext-Datei verwenden, so dass der Port ersetzt:
<contextFile>src/main/java/META-INF/tomcat/webapp-test-context-using-h2.xml</contextFile>
Mit dem Dateiinhalt Wesen:
<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"/>
Oder wenn Sie nicht über eine JNDI-Datenquelle möchten, können Sie einen Frühling verwenden Datasource deklariert, die die gleiche Eigenschaft mit ...
Eine zusätzliche Fahrt, wenn Sie Ihre Integrationstests tomcat einrichten können, wollen, und die Integrationstests von Ihrem IDE ausführen:
können Sie verwenden eine Eigenschaft verwenden, um die Gabel oder nicht der Tomcat-Server:
<fork>${integrationTestsForkTomcatJvm}</fork>
Wenn Sie setzen Gabel = false, wird der Server blockieren und Maven wird nicht fortgesetzt, so dass die Integrationstests werden nicht ausgeführt werden, aber Sie werden in der Lage, sie von Ihrem IDE auszuführen.
Ich habe gerade Projekt für H2-Plugin für Maven @ bitbucket gestartet. Ich werde mit ihm jede Hilfe dankbar.
https://bitbucket.org/dohque/maven-h2-plugin
Hoffe, dass es hilfreich sein wird.
In meinem Projekt, für Unit-Tests, fragte ich Frühling diese Datenbankerstellung und Initialisierung zu handhaben. Wie in der href="http://www.h2database.com/html/tutorial.html#spring" rel="nofollow noreferrer"> H2 Dokumentation
Sie müssen einfach den Frühling Zusammenhang mit dieser Konfiguration starten, wenn Sie Ihre Unit-Tests starten. <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>
Ich erstelle eine dateibasierte Datenbank H2 vor Unit-Tests ausgeführt werden. Die Datei lebt im target
Verzeichnis und kann jederzeit mit mvn clean
entfernt werden.
Ich verwende das Maven-SQL-Plugin wie folgt:
<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>
Die Datenbank kann durch Ausführen mvn process-test-resources
erstellt werden. Bei Tests ausgeführt werden, stellen Sie sicher, dass Sie in die Datenbank in target/db/testdb
über Hibernate Eigenschaften verbinden.
<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="" />
Sie werden auch zu einer Abhängigkeit von com.h2database.h2 müssen in Maven Abhängigkeiten.
Wenn Sie es im Speicher machen wollen, dann nur eine andere URL verwenden:
<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>
Sie können zusätzliche Optionen geben, wie zum Beispiel:; DB_CLOSE_DELAY = -1
siehe: http://www.h2database.com/html/features.html# in_memory_databases
Da H2 Maven bietet keine Plugin sollten Sie es mit Maven-antrun-Plugin starten. Schreiben von Code für Start und Stopp h2 Motors in Ant-Task und nennt es, wenn der Integrationstest startet und zu stoppen.
Siehe Details auf http://docs.codehaus.org/ Anzeige / MAVENUSER / Maven + und + Integration + Testing
Folgende macht den Job für mich (nur mit h2
Abhängigkeit und die 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>
Bitte beachten Sie, dass in meinem pom.xml
wurde der com.h2database:h2
nicht Abhängigkeit projizieren.
Für den Fall, würden Sie es haben Sie vielleicht nicht explizit als Plugin Abhängigkeit Namen tun müssen.