DeltaSpike DataをJava EEアプリケーションサーバー上で動かす(2)

前回のブログに引き続きDeltaSpike Dataを使ったJava EEアプリケーションをArquillianを使ってテストする方法について説明します。DeltaSpike Data自身はJava EEサーバーに依存していませんが、今回のサンプルプログラムはJPAのpersistence.xmlがデータベースにアクセスするのにWildFlyのデータソースを使っているのでテストを実行するにはWildFlyが必要になります。このようなアプリサーバーに依存するテストはArqullianを使うことで可能になります。

Arquillianとは

Java EE アプリケーションは、REST/CDI/EJB/JMSなどサーバー上のコンテナに依存することが多いのでJUnitを使ったテストの自動化は簡単ではありません。

ArquillianはJava EEアプリケーションのためのテスティング・フレームワークです。アプリケーションをJava EEサーバー上で動作させてテストをしたいとき、以下のような処理をしたいことがあります。

  • サーバーを起動する
  • アプリケーションをサーバーにデプロイする
  • サーバー上でテストを実行する
  • アプリケーションをサーバーからアンデプロイする
  • サーバーを停止する

Arquillianは、これらサーバーの起動・停止やデプロイ・アンデプロイを代わりにやってくれます。テストの実行は使い慣れたJUnit(やTestNG)を使います。しかも、JUNitのテストプログラムはサーバー上で実行され、CDIやEJBなどのBeanはテスト内にインジェクトして参照することができます。これにより、通常のJUnitを使ったテストと同様にテストをアプリサーバー上で実行することができます。

Arquillianテストプログラムの構造

Arquillianのテストプログラムは以下のような構造になります。

@RunWith(Arquillian.class) // (1)
public class MemberRegistrationTest {
    @Deployment // (2)
    public static Archive<?> createTestArchive() {
    ...
    }
    @Test // (3)
    public void testRegister() throws Exception {
    ...
    }
}
  • (1) @RunWith()でTestRunnerとしてArquillian.classを指定します。
  • (2) @DeploymentでアプリサーバーにデプロイするモジュールをShrinkWrap APIで作成します。
  • (3) @Testでテストメソッドを指定します。

この@Deploymentの部分がArquillian固有の特徴のある部分です。Arquillianではアプリサーバー上でテストプログラムを実行するためのアーカイブをShrinkWrapというAPIを使ってプログラムで作成します。これはメモリ上でアーカイブを作る操作になります。このアーカイブにはアプリケーションのすべてのクラスを含めるのではなく、テストに必要なクラスだけ含めるようにします。このようにアーカイブを作ることでデプロイするアーカイブのサイズを小さくできますし、テストの用途に応じて、クラスやデプロイメントディスクリプタを差し替えることも可能です。

Arquillianのテストプログラム

前回のブログで作成したアプリケーションは、Mavenアーキタイプによって生成しましたが、それにはすでにArquillianに対応したテストプログラムが付いていました。それをベースにDeltaSpike Data用に修正します。修正のポイントは以下の通り。

  • DataSpike Dataの依存ライブラリを追加する
  • アーカイブにDeltaSpike Dataを使ったMemberRepository.classを追加する
  • アーカイブにMETA-INF/apache-deltaspike.propertiesを追加する

注意:以下のテストプログラムでは直接MemberRepositoryを参照していませんが、MemberRegistrationのクラスにおいてそれをインジェクトしているために、アーカイブに含めておく必要があります。以下のサンプルではpom.xmlを参照して必要な依存ライブラリを抽出しています。

@RunWith(Arquillian.class)
public class MemberRegistrationTest {
    @Deployment
    public static Archive<?> createTestArchive() {
    	// DeltaSpike Dataの依存ライブラリをアーカイブに追加する
    	File[] files = Maven.resolver()
                .loadPomFromFile("pom.xml")
                //.importRuntimeDependencies().resolve()
                .resolve("org.apache.deltaspike.modules:deltaspike-data-module-api", "org.apache.deltaspike.modules:deltaspike-data-module-impl")
                .withTransitivity()
                .asFile();
    	
    	// アーカイブにテストプログラムが参照するクラスを追加する
    	Archive<?> archive = ShrinkWrap.create(WebArchive.class, "test.war")
                .addClasses(Member.class, MemberRepository.class, MemberRegistration.class, Resources.class)
                .addAsLibraries(files)
                .addAsResource("META-INF/test-persistence.xml", "META-INF/persistence.xml")
                .addAsResource("META-INF/test-apache-deltaspike.properties", "META-INF/apache-deltaspike.properties")
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
                // Deploy our test datasource
                .addAsWebInfResource("test-ds.xml");
    	
    	// デバッグ用にアーカイブの内容を標準出力に出力する
        System.out.println("archive=" + archive.toString(true));

        return archive;
    }

    @Inject
    MemberRegistration memberRegistration;

    @Inject
    Logger log;

    @Test
    public void testRegister() throws Exception {
	    Member newMember = new Member();
	    newMember.setName("Jane Doe");
	    newMember.setEmail("jane@mailinator.com");
	    newMember.setPhoneNumber("2125551234");
	    memberRegistration.register(newMember);
	    assertNotNull(newMember.getId());
	    log.info(newMember.getName() + " was persisted with id " + newMember.getId());  
    }
}

Arquillianの実行

Arquillianは内部でアプリサーバーと通信してテストケースを実行しますので、テストを実行するにはアプリサーバーを実行する必要があります。アプリサーバーの利用方法としては、remote/managed/embeddedの3種類が可能です。今回はテスト実行時にアプリサーバーの起動・停止をおこなうmanagedモードを選択します。

managedでWildFlyと通信可能にするため環境変数JBOSS_HOMEを設定してください(または、arquillian.xmlにWildFlyのパスを書くことで環境変数を設定しないことも可能です)。

テストの実行方法はmavenコマンドのプロファイルとしてarq-wildfly-managedを指定します。

mvn clean test -Parq-wildfly-managed

このテストを実行すると自動的にWildFlyが起動され、テストプログラムがWildFly上で実行されます。このプログラムではデバッグ用にアーカイブを標準出力に出していますが、その結果が以下にようになっています。DeltaSpike Dataが内部で使っているDeltaSpike Coreなどのjarがいくつも追加されている点に注意してください。

$ mvn clean test -Parq-wildfly-managed
[INFO] Scanning for projects…
[INFO]
[INFO] ————————————————————————
[INFO] Building WildFly Quickstarts: tanoseam-webapp 1.0.0-SNAPSHOT
[INFO] ————————————————————————
[INFO]
// (略)
00:12:57,148 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 10.0.0.CR4 (WildFly Core 2.0.0.CR8) started in 8679ms – Started 387 of 609 services (326 services are lazy, passive or on-demand)
archive=test.war:
/WEB-INF/
/WEB-INF/test-ds.xml
/WEB-INF/lib/
/WEB-INF/lib/deltaspike-partial-bean-module-impl-1.5.2.jar
/WEB-INF/lib/deltaspike-data-module-api-1.5.2.jar
/WEB-INF/lib/deltaspike-data-module-impl-1.5.2.jar
/WEB-INF/lib/deltaspike-core-impl-1.5.2.jar
/WEB-INF/lib/deltaspike-jpa-module-impl-1.5.2.jar
/WEB-INF/lib/deltaspike-proxy-module-api-1.5.2.jar
/WEB-INF/lib/deltaspike-proxy-module-impl-asm5-1.5.2.jar
/WEB-INF/lib/deltaspike-jpa-module-api-1.5.2.jar
/WEB-INF/lib/deltaspike-partial-bean-module-api-1.5.2.jar
/WEB-INF/lib/deltaspike-core-api-1.5.2.jar
/WEB-INF/classes/
/WEB-INF/classes/META-INF/
/WEB-INF/classes/META-INF/apache-deltaspike.properties
/WEB-INF/classes/META-INF/persistence.xml
/WEB-INF/classes/org/
/WEB-INF/classes/org/tanoseam/
/WEB-INF/classes/org/tanoseam/examples/
/WEB-INF/classes/org/tanoseam/examples/data/
/WEB-INF/classes/org/tanoseam/examples/data/MemberRepository.class
/WEB-INF/classes/org/tanoseam/examples/util/
/WEB-INF/classes/org/tanoseam/examples/util/Resources.class
/WEB-INF/classes/org/tanoseam/examples/service/
/WEB-INF/classes/org/tanoseam/examples/service/MemberRegistration.class
/WEB-INF/classes/org/tanoseam/examples/model/
/WEB-INF/classes/org/tanoseam/examples/model/Member.class
/WEB-INF/beans.xml// (略)

0:13:01,164 INFO [org.jboss.as] (MSC service thread 1-5) WFLYSRV0050: WildFly Full 10.0.0.CR4 (WildFly Core 2.0.0.CR8) stopped in 83ms

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ————————————————————————
[INFO] BUILD SUCCESS
[INFO] ————————————————————————
[INFO] Total time: 17.805 s
[INFO] Finished at: 2016-01-17T00:13:01+09:00
[INFO] Final Memory: 36M/395M
[INFO] ————————————————————————

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。