簡體   English   中英

如何:針對測試環境(數據庫)運行maven集成測試

[英]How to: Run maven integration tests against a test environment (database)

我正在使用maven和maven-failsafe-plugin在集成測試生命周期階段啟動jetty。 然后,我對運行的webapp執行了許多(* IT.java)junit測試。 這是按預期工作的。

但是,我想連接到測試數據庫進行集成測試。 我正在存儲它的URL

${basedir}/src/test/resources/jdbc.properties  

當jetty插件運行(jetty:run)時,它會使用

${basedir}/src/main/resources/jdbc.propertes 

代替。 property to use 我嘗試通過屬性重新配置jetty插件來使用

${project.build.testOutputDirectory}

但是test-classes目錄缺少我實際編譯的項目類,以及存儲的資源

${basedir}/src/main/resources 

注意:surefire將測試資源添加到類路徑中,然后是主資源,這樣兩者中的任何內容都將使用測試版本,因為它首先在類路徑中找到。

有關如何正確設置此設置的任何想法?

謝謝!

編輯:

好吧,似乎jetty-plugin上有配置屬性來處理這個問題:

  • testClassesDirectory:包含生成的測試類的目錄。
  • useTestClasspath:如果為true,則test的依賴項將首先放在運行時類路徑中。

不幸的是,它們不起作用。

這是我的pom.xml的相關部分:

  <testResources> <testResource> <filtering>true</filtering> <directory>src/test/resources</directory> </testResource> </testResources> <plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.26</version> <configuration> <contextPath>/</contextPath> <stopPort>8005</stopPort> <stopKey>STOP</stopKey> </configuration> <executions> <execution> <id>start-jetty</id> <phase>pre-integration-test</phase> <goals> <goal>run</goal> </goals> <configuration> <daemon>true</daemon> <useTestClasspath>true</useTestClasspath> <testClassesDirectory>${project.build.testOutputDirectory}</testClassesDirectory> </configuration> </execution> <execution> <id>stop-jetty</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-failsafe-plugin</artifactId> <version>2.6</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> <configuration> <useFile>false</useFile> </configuration> </plugin> 

我有同樣的問題,並通過使用自定義web.xml(jettyweb.xml)解決它看到maven configuarion

    <build>
    <plugins>

        <plugin>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>maven-jetty-plugin</artifactId>
            <configuration>
                <overrideWebXml>./src/main/webapp/WEB-INF/jettyweb.xml</overrideWebXml>
                <scanintervalseconds>3</scanintervalseconds>
            </configuration>
            <dependencies>

            </dependencies>
        </plugin>
    </plugins>

</build>

在我的例子中,我使用此配置來使用其他一些彈簧配置來管理事務。 但是這種策略也可以用於使用其他屬性文件。

我原來的web.xml有這個spring配置

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    /WEB-INF/spring-hibernate.xml,
    /WEB-INF/spring-services.xml
    </param-value>
</context-param>

我的jettyweb.xml有這個彈簧配置

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    /WEB-INF/spring-hibernate-jetty.xml,
    /WEB-INF/spring-services.xml
    </param-value>
</context-param>

這應該會讓你走上正確的道路

我用了

<configuration>
  <jettyEnvXml>src/test/webapp/WEB-INF/jetty-env.xml</jettyEnvXml>
  .
  .

內容

<?xml version="1.0"?>
    <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
    <New id="MyDb" class="org.mortbay.jetty.plus.naming.Resource">
        <Arg>jdbc/myDS</Arg>
        <Arg>
             <New class="org.apache.commons.dbcp.BasicDataSource">
                <Set name="driverClassName">org.h2.Driver</Set>
                <Set name="url">jdbc:h2:mem:testdb;INIT=CREATE SCHEMA IF NOT EXISTS TESTDB\;SET SCHEMA TESTDB</Set>
                <Set name="username">sa</Set>
                <Set name="password"></Set>
            </New>
         </Arg>
    </New>
</Configure>

我還需要在我的web.xml中

<resource-ref>
    <res-ref-name>jdbc/myDS</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

我用spring config

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/myDS" />
</bean>

我嘗試了兩位作者以及@thehpi的建議。 兩者都是可信的,但在我嘗試它們時遇到了一些問題。 我的設置是以下maven項目,使用與maven-failsafe-plugin集成測試,使用JPA和persistence.xml文件,用於告訴容器如何連接到數據庫。

簡而言之,下面詳細介紹了如何使用JVM屬性來告訴您的真實代碼只使用不同的persistence-unit 其他解決方案讓我在使用帶有Jetty 7的Hibernate 4.1時遇到了麻煩(找到數據源的問題)。

唯一的缺點是在項目的發布版本中最終會出現無用的配置。 輔助持久性單元永遠不會在maven集成測試之外使用。 我確定有一種方法可以解決它,但對我來說,我對這種方法很滿意。 我甚至將hsqldb.jar從構建中拉出來,並使其成為僅對插件執行的依賴。

來自POM的相關信息

<plugin>
    <inherited>true</inherited>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.8.1</version>
</plugin>
<plugin>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>7.2.0.v20101020</version>
    <dependencies>
        <dependency>
            <groupId>hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>1.8.0.10</version>
        </dependency>
    </dependencies>
    <configuration>
        <scanIntervalSeconds>10</scanIntervalSeconds>
        <stopPort>8005</stopPort>
        <stopKey>STOP</stopKey>
        <contextPath>/</contextPath>
    </configuration>

    <executions>
        <execution>
            <id>start-jetty</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <scanIntervalSeconds>0</scanIntervalSeconds>
                <daemon>true</daemon>
                <systemProperties>
                    <systemProperty>
                        <name>RUNNING_TESTS</name>
                        <value>true</value>
                    </systemProperty>
                </systemProperties>
            </configuration>
        </execution>
        <execution>
            <id>stop-jetty</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>stop</goal>
            </goals>
        </execution>
    </executions>
</plugin>

請注意名為“RUNNING_TESTS”的System屬性。

HibernateUtil.java

public class HibernateUtil {
    private static final EntityManagerFactory emfInstance;
    static {
        String istest = System.getProperty("RUNNING_TESTS");
        System.out.println("RUNNING_TESTS: " + istest);
        if (istest != null && istest.equalsIgnoreCase("true")) {
            emfInstance = Persistence.createEntityManagerFactory("integration-tests");
        }
        else {

            emfInstance = Persistence.createEntityManagerFactory("productionname");
        }
    }

    public static EntityManagerFactory getInstance() {
        return emfInstance;
    }

    private HibernateUtil() {
    }
}

persistence.xml (在/ src / main / resources / META-INF中)

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">

    <!-- persistence.xml -->
    <persistence-unit name="productionname">

        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <non-jta-data-source>java:comp/env/jdbc/selectivemailpush</non-jta-data-source>
        <properties>
            <property name="hibernate.archive.autodetection" value="class, hbm" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
        </properties>
    </persistence-unit>

    <persistence-unit name="integration-tests">

        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>...</class>
        <class>...</class>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
            <property name="hibernate.connection.username" value="sa" />
            <property name="hibernate.connection.password" value="" />
            <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:integration-tests" />
            <property name="hibernate.showSql" value="true" />
            <property name="hibernate.format_sql" value="true" />
        </properties>

    </persistence-unit>

</persistence>

我正在努力解決同樣的問題,但我認為useTestClasspath似乎不起作用的原因實際上在於Spring。

您可能具有如下配置:

<context:property-placeholder location="classpath*:**/*.properties"/>

如果刪除第一個*我認為它有效,因為使用此配置它從不同位置加載相同的屬性文件(主要和測試,如果兩者都存在)。 刪除*只會加載測試版。 所以改成它

<context:property-placeholder location="classpath:**/*.properties"/>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM