Cara: Menjalankan pengujian integrasi maven terhadap lingkungan pengujian (database)

Saya menggunakan maven dan maven-failsafe-plugin untuk memulai jetty selama fase siklus hidup pengujian integrasi. Saya kemudian menjalankan sejumlah tes junit (*IT.java) terhadap aplikasi web saya yang sedang berjalan. Ini berfungsi seperti yang diharapkan.

Namun, saya ingin terhubung ke database pengujian untuk pengujian integrasi saya. Saya menyimpan urlnya di

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

Saat plugin jetty berjalan (jetty:run), ia menggunakan

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

alih-alih. Saya mencoba mengkonfigurasi ulang plugin jetty melalui properti classesDirectory untuk digunakan

${project.build.testOutputDirectory}

tetapi direktori test-classes tidak memiliki kelas proyek terkompilasi saya yang sebenarnya, serta sumber daya yang disimpan di dalamnya

${basedir}/src/main/resources 

catatan: pasti menambahkan sumber daya pengujian ke classpath, diikuti oleh sumber daya utama, sehingga apa pun yang ditemukan di keduanya akan menggunakan versi pengujian karena ditemukan pertama kali di classpath.

Adakah ide tentang cara menyiapkan ini dengan benar?

Terima kasih!

Sunting:

Tampaknya ada properti konfigurasi di jetty-plugin untuk menangani hal ini:

  • testClassesDirectory : Direktori yang berisi kelas pengujian yang dihasilkan.
  • useTestClasspath : Jika benar, dependensi pengujian akan diprioritaskan pada classpath runtime.

Sayangnya, mereka tidak berhasil.

Inilah bagian yang relevan dari pom.xml saya:

  <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 sumber
comment
Bisakah Anda menambahkan bagian yang relevan di POM Anda?   -  person Chris K    schedule 18.02.2011
comment
Terima kasih, ini banyak membantu saya. Satu hal yang perlu diperhatikan adalah saya mencoba menggunakan tujuan run-exploded (sesuai dokumentasi failsafe), yang tidak mendukung useTestClassPath atau testClassesDirectory.   -  person Domenic D.    schedule 08.11.2012


Jawaban (4)


Saya memiliki masalah yang sama, dan menyelesaikannya dengan menggunakan web.xml khusus (jettyweb.xml) lihat konfigurasi 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>

Dalam kasus saya, saya menggunakan konfigurasi ini untuk menggunakan beberapa konfigurasi pegas lainnya untuk mengelola transaksi. Namun strategi ini juga dapat digunakan untuk menggunakan file properti lainnya.

Web.xml asli saya memiliki konfigurasi pegas ini

<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 saya memiliki konfigurasi pegas ini

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

Ini akan menempatkan Anda di jalur yang benar

person Mark Bakker    schedule 23.02.2011

saya menggunakan

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

dengan isinya

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

Saya juga membutuhkan di web.xml saya

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

Saya menggunakan konfigurasi pegas

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

Saya mencoba saran penulis dan @thehpi. Keduanya kredibel, namun ada beberapa masalah saat saya mencobanya. Pengaturan saya adalah sebagai berikut, proyek pakar, menggunakan tes integrasi dengan maven-failsafe-plugin, menggunakan JPA dengan file persistence.xml yang digunakan untuk memberi tahu wadah cara terhubung ke database.

Singkat cerita, yang dirinci di bawah ini adalah cara menggunakan properti JVM untuk memberi tahu kode asli Anda agar menggunakan persistence-unit yang berbeda. Solusi lain membuat saya kesulitan menggunakan Hibernate 4.1 dengan Jetty 7 (masalah dalam menemukan sumber data).

Satu-satunya kelemahan adalah Anda akan mendapatkan konfigurasi yang tidak berguna dalam versi rilis proyek Anda. Unit persistensi sekunder tidak akan pernah digunakan di luar uji integrasi maven. Saya yakin ada cara untuk membaginya, tetapi bagi saya, saya setuju dengan pendekatan ini. Saya bahkan telah menarik hsqldb.jar keluar dari build dan menjadikannya ketergantungan hanya untuk eksekusi plugin.

Relevan dari Badan 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>

Perhatikan properti Sistem yang disebut "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 (di /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

Saya mengalami masalah yang sama, tetapi menurut saya alasan mengapa useTestClasspath tampaknya tidak berfungsi sebenarnya terletak pada Musim Semi.

Anda mungkin memiliki konfigurasi seperti berikut:

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

Jika Anda menghapus yang pertama * Saya pikir ini berfungsi karena dengan konfigurasi ini ia memuat file properti yang sama dari lokasi yang berbeda (baik utama dan uji apakah ada di keduanya). Menghapus * hanya akan memuat tes. Jadi ubahlah menjadi

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