Webサービスを提供するwebappがあります。 SoapUIでJUnitテストを実行して、このサービスが適切に機能しているかどうかを確認したいと思います。
しかし、Webサービスアプリケーションをテストするには、Tomcat 7サーバーにデプロイする必要があります。
Mavenを構成してwarを構築し、それをTomcatにデプロイして(理想的には、このために別のTomcatインスタンスを実行する)、JUnitテストを実行する方法がわかりません。
どんな助けにも感謝します。
私はMaven 2.2.1を使用しています
Mavenでこのタイプの統合テストを処理する方法については、多くの考え方があります。
アプリケーションサーバーにアプリケーションをデプロイするときは、ユニットテストの領域にはもういません。アプリケーション全体がコンテナ内にデプロイされているため、これら2つのコンポーネントの統合をテストしています。
統合テストを実行するためにJUnitを使用しても何も問題はありません(ただし、たとえばユニットテストは、個々のテストのシーケンスについて気にする必要はありませんが、いくつかの制限があります) -正しく記述していると仮定-JUnit enforcesこれは、実行の順序を保証しないためです... Java 1.7より前のバージョンでは、テストの順序によって実行順序が誤って暗示されていました。クラス内のメソッドですが、JUnitコントラクトの一部ではありません... 統合テスト、たとえばTestNGなど、他のテストフレームワークに切り替えて単体テストフォーカスを見つけた場合のJUnitがテスト開発の邪魔になっています)
覚えておくべき重要な点は、Mavenライフサイクルがnitテストの実行にtest
フェーズを使用することです。
integrationテストに関しては、Mavenでテストを処理するための正しい方法について、2つ(および半分)の考え方があります。
integration-test/verify
この考え方では、package
の後のフェーズを使用してコンテナを起動し、統合テストを実行し、コンテナを破棄し、最後にテスト結果を確認し、テストが失敗した場合はビルドを失敗させます。
NEVER EVER RUN mvn integration-test
]とすると、コンテナが正しく破棄されないため、mvn integration-test
と入力したいと思うときはいつでも、実際にmvn verify
と入力したいと思います(ああ、そうです。短くてタイプも簡単...ボーナス)
したがって、これを使用して次のことを行います。
fork
pre-integration-test
で Tomcat7:run を=true
フェーズにバインドしますintegration-test
フェーズにバインドpost-integration-test
フェーズにバインドverify
フェーズにバインドします。追加のブラウニーポイントについては、 build-helper-maven-plugin:reserve-network-port をvalidate
フェーズにバインドして、テストサーバーが未使用のネットワークポートで確実に起動されるようにします。次に、テストリソースに対してリソースフィルタリングを使用して、ポートをテストに渡すか、または systemPropertyVariables を介して渡されるシステムプロパティを使用して、ポート番号をテストで使用できるようにします。
run-its
と呼ばれます)。IT
で開始/終了し、MavenはSurefireでTest
で開始/終了するテストを実行し、FailsafeでIT
で開始/終了するテストを実行することを知っています。 IDEはおそらくそうではありません。さらに、IDEがコンテナを起動することはないため、実際にテストを手動で実行するには、手作業で多くの作業を行う必要があります。テストをデバッグするには、2つのデバッガー(例: 1つはコンテナで実行されているアプリケーションをデバッグするためのもので、もう1つは テストケースをデバッグする のためのものです。
mvnDebug -Dmaven.failsafe.debug=true verify
テストをMavenビルドプロセスに結合します。
この考え方では、統合テストをwar
モジュールに依存する別のモジュールに移動し、war
をテストリソースにコピーします。 dependency:copy-dependencies
テストするTomcat7依存関係と結合されたgenerate-test-resources
フェーズにバインドされます。
テストケース自体が 組み込みモード を使用してTomcat7コンテナを起動します
war
アーティファクトは、package
フェーズを通過した場合にのみ再構築されるため、IDEを使用する場合、テスト対象のコードを更新するために少なくともmvn clean package
を定期的に実行する必要があります。war
モジュールのビルドを中断しません。そのため、壊れたwar
アーティファクトをリリースして、統合テストモジュールのreactorビルドを失敗させることができます。一部の人々は、src/it
内に統合テストモジュールを配置し、Maven Invokerプラグインを使用してテストを実行することでこの問題に対処しています...しかし、これはIDE統合をより貧弱にするため、その行はお勧めしません。これは、2つのアプローチの一種のハイブリッドです。
Failsafeを使用してテストを実行しますが、テスト自体は、テストするTomcat7コンテナーの開始と停止を担当します。
上記があなたがあなたが持っているオプションを理解するのに役立つことを願っています。他の微調整があるかもしれませんが、一般的に上記は現在Mavenとの統合テストのベストプラクティスと考えられています。
@Stephen Connolly-上記の回答は本当に良かったです。私はあなたがSchool 1
レスポンスと呼んだものの完全な設定を開始して表示すると思いました。
この構成:
@Category
アノテーションを使用します。依存するアプリケーションにのみ特定のシステムプロパティを設定する方法など、他にもあります。
これまでのところ、この構成は素晴らしいです。
<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が説明するように、これを直接構成する方法はありません。フェイルセーフプラグインを使用してこれを解決する方法を説明します。 Mavenライフサイクルでは、テストのタイプをテストできます。そのうちの1つともう1つを統合テストする単体テストです。単体テストは、Mavenライフサイクルのテスト段階で実行できます。統合テストを行う場合は、検証段階で行うことができます。単体テストと統合テストの違いを知りたい場合、これは 良いもの です。デフォルトでは、ユニットテストクラスは***/*Test.Java
であり、**/*TestCase.Java
この形式である必要があります。フェイルセーフプラグインは、**/IT*.Java
、**/*IT.Java
、を検索します**/*ITCase.Java
。
ここに、1つの単体テストクラスと1つの統合テストクラスがあります。ここで、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ファイル)をデプロイする前に実行されます。ただし、統合テストは検証段階で実行されます。この段階であなたの要求が満たされれば幸いです。