Arquillian + AS7を見てみる
7月12日に、JBoss Application Server 7 (AS7) がリリースされた*1。機能面の紹介は本家のページやこちらに譲るとして、リリース当初から結合テストフレームワークである、Arquillianをサポートしているところに注目したい。
ということで、この記事ではAS7とArquillianでどのようにテストを行うかを見ていく。
これまで、JavaEEのコンポーネントをJUnitなどテスティングフレームワークで統合テストをするのはなかなか難しかった。DIが普及しているし、JavaEE5からはPOJOを利用できるようになったので、単体テストはずっと容易になったけれども、実際にデプロイしてみないとテストできないこともたくさんあり、これについてはいろんな人がさまざまな試みをしてきている。
xUnit Test Patterns: Refactoring Test Code (Addison-Wesley Signature Series (Fowler))
- 作者: Gerard Meszaros
- 出版社/メーカー: Addison-Wesley Professional
- 発売日: 2007/05/21
- メディア: ハードカバー
- 購入: 5人 クリック: 210回
- この商品を含むブログ (66件) を見る
Test Driven: TDD and Acceptance TDD for Java Developers
- 作者: Lasse Koskela
- 出版社/メーカー: Manning Publications
- 発売日: 2007/10/22
- メディア: ペーパーバック
- 購入: 1人 クリック: 25回
- この商品を含むブログ (6件) を見る
- remote
- managed
- embedded
- 内部のコンテナを利用してテスト。コンテナとテストケースのJVMは同一。
対応済みのコンテナは、こちらにあるようにJBoss AS5〜7、GlassFish 3.1、Weld SE 1.0、1.1など。また、GitHubには、OpenShiftやWebSphere、Springコンテナ用のプロジェクトも、一応存在している。一応。
自分でコードを書いて試したいところだが、まずは、ドキュメントで紹介されている、サンプルコードを見てみる。まずは、ASダウンロードのページから、"Quick Starts"をダウンロードする。ダウンロードしたjboss-as-quickstarts-7.0.0.Final-dist.zipを展開すると、以下のようにプロジェクトがいくつかある。
jboss-as-quickstarts-7.0.0.Final% ls -F helloworld/ helloworld-osgi/ kitchensink/ login/ numberguess/ pom.xml README.md
Arquillianのサンプルは、kitchensinkにある。
以下の内容は、Arquillianのドキュメント Chapter 3. Getting started*2と、kitchensinkを元にしている。また今回は、pom.xmlとテストコードのみさらっと見てみる。
kitchensink/pom.xml
まずJUnitを利用するArquillianを設定している。バージョンは1.0.0.CR1*3。
<dependency> <groupId>org.jboss.arquillian.junit</groupId> <artifactId>arquillian-junit-container</artifactId> <version>1.0.0.CR1</version> <scope>test</scope> </dependency>
テスト時に利用するAPIをdependencyとして指定している。
<dependency> <groupId>org.jboss.spec</groupId> <artifactId>jboss-javaee-web-6.0</artifactId> <version>2.0.0.Final</version> <type>pom</type> <scope>provided</scope> </dependency>
前述のようにJUnitを利用する。
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency>
テスト環境をprofileとして指定。これはmanaged設定。
<profile> <!-- An optional Arquillian testing profile that executes tests in your JBoss AS instance --> <!-- This profile will start a new JBoss AS instance, and execute the test, shutting it down when done --> <!-- Run with: mvn clean test -Parq-jbossas-managed --> <id>arq-jbossas-managed</id> <dependencies> <dependency> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-arquillian-container-managed</artifactId> <version>7.0.0.CR1</version> <scope>test</scope> </dependency> </dependencies> </profile>
おなじくテスト環境をprofileとして指定。これはremote設定。
<profile> <!-- An optional Arquillian testing profile that executes tests in a remote JBoss AS instance --> <!-- Run with: mvn clean test -Parq-jbossas-remote --> <id>arq-jbossas-remote</id> <dependencies> <dependency> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-arquillian-container-remote</artifactId> <version>7.0.0.CR1</version> <scope>test</scope> </dependency> </dependencies> </profile>
kitchensink/src/test/resources/arquillian.xml
arquillian.xmlにはテスト環境に依存する設定を記述する。例えばJBossの配置場所。
<container qualifier="jboss" default="true"> <protocol type="jmx-as7"> <property name="executionType">REMOTE</property> </protocol> <configuration> <property name="jbossHome">/path/to/jboss/as</property> </configuration> </container>
kitchensink/src/test/java/org/jboss/as/quickstarts/kitchensink/test/MemberRegistrationTest.java
最後にテストコード。
- @RunWithアノテーションで、Arquillianクラスを指定
- @Deploymentのついたメソッドで、テスト対象のクラスをWARファイルとしてまとめてコンテナにデプロイ
- @Injectを利用可能。
- @Testのついたメソッドで、テスト実行
@RunWith(Arquillian.class) public class MemberRegistrationTest { @Deployment public static Archive<?> createTestArchive() { return ShrinkWrap.create(WebArchive.class, "test.war") .addClasses(Member.class, MemberRegistration.class, Resources.class) .addAsResource("META-INF/persistence.xml", "META-INF/persistence.xml") .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); } @Inject MemberRegistration memberRegistration; @Inject Logger log; @Test public void testRegister() throws Exception { Member newMember = memberRegistration.getNewMember(); newMember.setName("Jane Doe"); newMember.setEmail("jane@mailinator.com"); newMember.setPhoneNumber("2125551234"); memberRegistration.register(); assertNotNull(newMember.getId()); log.info(newMember.getName() + " was persisted with id " + newMember.getId()); } @Produces public Logger produceLog(InjectionPoint injectionPoint) { return Logger.getLogger(injectionPoint.getMember().getDeclaringClass()); } }
JBOSS_HOMEの設定やらMavenリポジトリの設定やらが適正であれば、以下のようにテストが成功する。
*4
jboss-as-quickstarts-7.0.0.Final/kitchensink% mvn test -Parq-jbossas-managed [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building JBoss AS Quickstarts: Kitchensink 7.0.0.Final [INFO] ------------------------------------------------------------------------ (略) ------------------------------------------------------- T E S T S ------------------------------------------------------- Running org.jboss.as.quickstarts.kitchensink.test.MemberRegistrationTest (略) Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 11.82 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 13.765s [INFO] Finished at: Fri Aug 05 00:17:07 JST 2011 [INFO] Final Memory: 11M/298M [INFO] ------------------------------------------------------------------------
ちなみに以下のアイコンもある。*5
Warning | Failure | Error |
…明日は早起きしなくちゃいけないので今日はここまで。