簡體   English   中英

Maven - 在JUnit測試之前將webapp部署到tomcat

[英]Maven - deploy webapp to tomcat before JUnit test

我有webapp,提供Web服務。 我想用SoapUI執行JUnit測試以檢查此服務是否正常工作。
但要測試Web服務應用程序必須部署到我的Tomcat 7服務器。

我不知道如何配置maven來構建war,然后將其部署到tomcat(理想情況下:為此運行單獨的tomcat實例)然后運行JUnit測試。
我將不勝感激任何幫助。

我正在使用maven 2.2.1

關於如何使用Maven處理這種類型的集成測試 ,有許多思想流派。

我應該指出,當您將應用程序部署到應用程序服務器時,您不再需要進行單元測試。 因為整個應用程序正在一個容器中部署,所以您正在測試這兩個組件的集成。

現在使用JUnit來運行集成測試沒有任何問題(雖然你可能會遇到一些限制,例如單元測試不應該關心單個測試的順序 - 假設你正確地編寫它們 - 所以JUnit 強制執行此操作保證任何執行順序......在Java 1.7之前,執行順序是由類中的測試方法的順序意外隱含的,但它不是JUnit合同的一部分......有些人切換到其他測試框架進行集成測試,例如TestNG,如果他們發現JUnit的單元測試焦點正在妨礙他們的測試開發)

要記住的關鍵點是Maven生命周期使用test階段來執行單元測試。

集成測試方面,有兩種(一半)思想流派可以使用Maven來處理測試。

學校1 - 故障安全和integration-test/verify

這種思想使用package后的階段來啟動容器,運行集成測試,拆除容器,最后檢查測試結果並在測試失敗的情況下使構建失敗。

永遠不要運行mvn integration-test因為這不會正確地拆除容器,任何時候你想要輸入mvn integration-test你實際上想要輸入mvn verify (哦看,它更短更容易輸入...獎金)

因此,您可以執行以下操作:

對於額外的布朗尼點,您將使用build-helper-maven-plugin:reserve-network-port綁定到validate階段,以確保測試服務器在未使用的網絡端口上啟動,然后使用針對測試資源的資源過濾來傳遞端口直到測試或使用通過systemPropertyVariables傳遞的系統屬性來使測試可用的端口號。

好處

  • 清潔Maven構建
  • 如果測試失敗,則無法釋放項目
  • 如果測試速度太慢而無法運行每個構建,可以將集成測試移動到單獨的配置文件中(按慣例稱為run-its )。

缺點

  • 很難從IDE運行測試。 所有集成測試都在IT開始/結束,而Maven知道在Surefire中使用Test開始/結束Test ,並使用Failsafe在IT開始/結束測試,您的IDE可能不會。 此外,您的IDE不會為您啟動容器,因此您必須手動執行大量工作才能實際運行測試。
  • 調試測試可能需要附加兩個調試器,例如一個調試在容器中運行的應用程序,另一個調試測試用例

     mvnDebug -Dmaven.failsafe.debug=true verify 
  • 將您的測試與Maven構建過程相結合。

學校2 - 單獨的模塊

這一學派的集成測試移動成依賴於一個單獨的模塊war模塊和副本war成使用測試資源,如dependency:copy-dependencies綁定到generate-test-resources再加上Tomcat7依賴階段測試反對。

測試用例本身使用嵌入模式啟動Tomcat7容器

好處

  • 測試可以在IDE中運行
  • 集成測試與單元測試分開,因此要求IDE運行所有測試不會啟動較慢的測試

缺點

  • 只有經過package階段才會重建war工件,因此,在使用IDE時,您需要定期運行至少mvn clean package以刷新測試中的代碼。
  • 集成測試的失敗不會破壞war模塊的構建,因此您最終可能會釋放出一個破壞的war偽像,然后讓集成測試模塊的reactor構建失敗。 有些人通過在src/it使用集成測試模塊並使用Maven Invoker插件來運行測試來抵消這個問題......雖然這提供了較差的IDE集成,所以我不推薦這一行。
  • 很難從Maven獲得一份綜合的測試報告。
  • 必須在測試用例中對容器的啟動/停止進行編碼。

School 2.5 - 測試用例啟動自己的Tomcat7服務器時出現故障

這是兩種方法的混合體。

您使用Failsafe來執行測試,但測試本身負責啟動和停止您要測試的Tomcat7容器。

好處

  • 不必在Maven pom中配置服務器啟動/停止
  • IDE可以安全地運行所有測試(盡管集成測試可能會更慢並且您可能不想運行它們,但它們並不像它們都會失敗,除非測試失敗)
  • 更容易從IDE調試測試(只有一個連接過程,IDE通常可以通過提供特殊的測試運行器來輕松調試測試)

缺點

  • 必須在測試用例中對容器的啟動/停止進行編碼

我希望上面的內容可以幫助您了解您的選擇。 可能還有其他調整,但總的來說,上面被認為是目前與Maven進行集成測試的最佳實踐。

@Stephen Connolly - 你上面的回答非常好。 我以為我會開始為你所謂的School 1回應展示一個完整的配置。

這個配置:

  • 與集成測試分開運行單元測試。 它在單元測試和集成測試擴展的根類上使用@Category注釋。
  • 在集成測試之前,它通過查找開放端口在本地計算機上啟動依賴應用程序(在運行時作為maven依賴項加載)
  • 在集成測試之后,它會刪除依賴的應用程序

還有其他的東西,比如如何僅在依賴應用程序上設置某些系統屬性。

到目前為止這個配置工作真棒..

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
            <version>1.9.1</version>
            <executions>
                <execution>
                    <id>reserve-network-port</id>
                    <goals>
                        <goal>reserve-network-port</goal>
                    </goals>
                    <phase>pre-integration-test</phase>
                    <configuration>
                        <portNames>
                            <portName>tomcat.maven.http.port</portName>
                        </portNames>
                    </configuration>
                </execution>
                <execution>
                    <id>get-local-ip</id>
                    <goals>
                        <goal>local-ip</goal>
                    </goals>
                    <configuration>
                        <!-- if not given, 'local.ip' name is used -->
                        <localIpProperty>local.ip</localIpProperty>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <!-- http port from reserve-network-port-plugin-->
                <port>${tomcat.maven.http.port}</port>
                <!-- application path always starts with /-->
                <path>/</path>
                <webapps>
                    <webapp>
                        <groupId>com.company.other.app</groupId>
                        <artifactId>web-rest</artifactId>
                        <version>1.0.1-SNAPSHOT</version>
                        <type>war</type>
                        <contextPath>/webapi-loopback</contextPath>
                        <asWebapp>true</asWebapp>
                    </webapp>
                </webapps>
            </configuration>
            <executions>
                <execution>
                    <id>start-server</id>
                    <configuration>
                        <fork>true</fork>
                        <skip>${skipTests}</skip>
                        <systemProperties>
                            <spring.profiles.active>test,h2</spring.profiles.active>
                        </systemProperties>
                    </configuration>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
                <execution>
                    <id>stop-server</id>
                    <configuration>
                        <skip>${skipTests}</skip>
                    </configuration>
                    <phase>post-integration-test</phase>
                    <goals>
                        <goal>shutdown</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19</version>
            <configuration>
                <excludedGroups>com.company.app.service.IntegrationTestRootClassAnnotatedWithAtCategory</excludedGroups>
            </configuration>
            <executions>
                <execution>
                    <id>unit-test</id>
                    <phase>test</phase>
                    <goals>
                        <goal>test</goal>
                    </goals>
                    <configuration>
                        <argLine>-Xmx1024m -XX:MaxPermSize=256m @{jacocoArgLine}</argLine>
                        <excludedGroups> com.company.app.service.IntegrationTestRootClassAnnotatedWithAtCategory </excludedGroups>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.18</version>
            <dependencies>
                <dependency>
                    <groupId>org.apache.maven.surefire</groupId>
                    <artifactId>surefire-junit47</artifactId>
                    <version>2.18</version>
                </dependency>
            </dependencies>
            <executions>
                <execution>
                    <id>start-integration-test</id>
                    <phase>integration-test</phase>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                    <configuration>
                        <argLine>-Xmx1024m -XX:MaxPermSize=256m @{jacocoArgLine}</argLine>
                        <groups>com.company.app.IntegrationTestRootClassAnnotatedWithAtCategory</groups>
                        <includes>
                            <include>**/*.java</include>
                        </includes>
                        <systemPropertyVariables>
                            <program.service.url>
                                http://${local.ip}:${tomcat.maven.http.port}/webapi-loopback
                            </program.service.url>
                        </systemPropertyVariables>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

正如Stephen Connolly解釋的那樣,沒有直接的方法來配置它。 我將解釋如何使用failsafe插件解決這個問題。 在maven生命周期中可以測試類型的測試。 單元測試其中一個,另一個是集成測試。 單元測試可以在maven生命周期的測試階段運行。 當您想要進行集成測試時,可以在驗證階段完成。 如果你想知道單元測試和集成測試之間的區別,這是一個很好的 默認情況下,單元測試類應該在***/*Test.java**/*TestCase.java這種格式中。 故障安全插件將查找**/IT*.java**/*IT.java**/*ITCase.java

這是一個例子。 在此輸入圖像描述

這里我有一個單元測試類和一個集成測試類。 現在我要解釋一下,看起來應該是maven pom.xml。 maven配置的構建部分應該如下所示。

<build>
    <plugins>
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <webXml>src/main/webapp/WEB-INF/web.xml</webXml>
                <warName>${name}</warName>
                <outputDirectory>/home/jobs/wso2/wso2as-5.3.0/repository/deployment/server/webapps</outputDirectory>
                <goal>
                </goal>
            </configuration>
        </plugin>

        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.12.4</version>
            <executions>
                <execution>
                    <id>integration-test</id>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>

在部署Web應用程序(war文件)之前運行單元測試。 但集成測試在驗證階段運行。 我希望在這個階段你的要求得到滿足。

暫無
暫無

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

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