วิธีการ: รันการทดสอบการรวม Maven กับสภาพแวดล้อมการทดสอบ (ฐานข้อมูล)

ฉันใช้ maven และ maven-failsafe-plugin เพื่อเริ่มต้นท่าเทียบเรือในระหว่างขั้นตอนวงจรการใช้งานการทดสอบการผสานรวม จากนั้น ฉันดำเนินการทดสอบ Junit (*IT.java) จำนวนหนึ่งกับเว็บแอปที่ทำงานอยู่ สิ่งนี้ทำงานได้ตามที่คาดไว้

อย่างไรก็ตาม ฉันต้องการเชื่อมต่อกับฐานข้อมูลทดสอบสำหรับการทดสอบการรวมระบบของฉัน ฉันกำลังเก็บ url ของมันเอาไว้

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

เมื่อปลั๊กอินท่าเทียบเรือทำงาน (ท่าเทียบเรือ: เรียกใช้) จะใช้

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

แทน. ฉันพยายามกำหนดค่าปลั๊กอิน Jetty ใหม่ผ่านคุณสมบัติ classesDirectory ที่จะใช้

${project.build.testOutputDirectory}

แต่ไดเร็กทอรี test-classes ขาดคลาสโปรเจ็กต์ที่คอมไพล์ตามจริงของฉัน รวมถึงทรัพยากรที่เก็บไว้

${basedir}/src/main/resources 

หมายเหตุ: Surefire จะเพิ่มทรัพยากรการทดสอบลงใน classpath ตามด้วยทรัพยากรหลัก ดังนั้นสิ่งใดก็ตามที่พบในทั้งสองจะใช้เวอร์ชันทดสอบเนื่องจากพบก่อนใน classpath

มีความคิดเห็นเกี่ยวกับวิธีตั้งค่านี้อย่างถูกต้องหรือไม่

ขอบคุณ!

แก้ไข:

ดูเหมือนว่าจะมีคุณสมบัติการกำหนดค่าบน jetty-plugin เพื่อจัดการกับสิ่งนี้:

  • testClassesDirectory : ไดเร็กทอรีที่มีคลาสการทดสอบที่สร้างขึ้น
  • useTestClasspath : หากเป็นจริง การขึ้นต่อกันของการทดสอบจะถูกใส่ไว้เป็นอันดับแรกบนคลาสพาธรันไทม์

น่าเสียดายที่มันไม่ได้ผล

นี่คือส่วนที่เกี่ยวข้องของ 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>

person Jon Lorusso    schedule 18.02.2011    source แหล่งที่มา
comment
คุณสามารถเพิ่มส่วนที่เกี่ยวข้องของ POM ของคุณได้หรือไม่?   -  person Chris K    schedule 18.02.2011
comment
ขอบคุณ สิ่งนี้ช่วยฉันได้มาก สิ่งหนึ่งที่ควรทราบคือฉันกำลังพยายามใช้เป้าหมาย run-exploded (ตามเอกสารประกอบความปลอดภัย) ซึ่งไม่รองรับ useTestClassPath หรือ testClassesDirectory   -  person Domenic D.    schedule 08.11.2012


คำตอบ (4)


ฉันมีปัญหาเดียวกันนี้ และแก้ไขได้โดยใช้ web.xml ที่กำหนดเอง (jettyweb.xml) ดูการกำหนดค่า maven

    <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 ดั้งเดิมของฉันมีการกำหนดค่าสปริงนี้

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

สิ่งนี้จะทำให้คุณอยู่ในเส้นทางที่ถูกต้อง

person Mark Bakker    schedule 23.02.2011

ฉันใช้

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

ฉันใช้การกำหนดค่าสปริง

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

ฉันลองทั้งผู้เขียนและคำแนะนำ @thehpi ทั้งสองมีความน่าเชื่อถือ แต่มีปัญหาบางอย่างเมื่อฉันลองใช้ การตั้งค่าของฉันเป็นไปตามโครงการ maven โดยใช้การทดสอบการรวมกับ maven-failsafe-plugin โดยใช้ JPA กับไฟล์ Peristence.xml ที่ใช้เพื่อบอกคอนเทนเนอร์ว่าจะเชื่อมต่อกับฐานข้อมูลอย่างไร

เรื่องสั้นโดยสรุป สิ่งที่มีรายละเอียดด้านล่างนี้คือวิธีใช้คุณสมบัติ JVM เพื่อบอกโค้ดจริงของคุณให้ใช้ persistence-unit อื่น วิธีแก้ปัญหาอื่น ๆ ทำให้ฉันมีปัญหาในการใช้ Hibernate 4.1 กับ Jetty 7 (ปัญหาในการค้นหาแหล่งข้อมูล)

ข้อเสียเปรียบเพียงอย่างเดียวคือคุณจะพบกับการกำหนดค่าที่ไม่มีประโยชน์ในเวอร์ชันที่เผยแพร่ของโปรเจ็กต์ของคุณ หน่วยการคงอยู่รองจะไม่ถูกใช้นอกการทดสอบการรวม 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"

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>
person Domenic D.    schedule 08.11.2012

ฉันกำลังดิ้นรนกับปัญหาเดียวกัน แต่ฉันคิดว่าเหตุผลที่ useTestClasspath ดูเหมือนจะไม่ทำงานนั้นจริงๆ แล้วอยู่ใน Spring

คุณอาจมีการกำหนดค่าดังต่อไปนี้:

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

หากคุณลบอันแรก * ฉันคิดว่ามันใช้งานได้เพราะด้วยการกำหนดค่านี้จะโหลดไฟล์คุณสมบัติเดียวกันจากตำแหน่งที่แตกต่างกัน (ทั้งหลักและทดสอบว่ามีอยู่ในทั้งสองแห่งหรือไม่) การลบ * จะโหลดเฉพาะการทดสอบเท่านั้น เลยเปลี่ยนให้เป็น

<context:property-placeholder location="classpath:**/*.properties"/>
person Werner Altewischer    schedule 20.05.2011