Getting Started
このガイドではArquillianを紹介します。このガイドを読むと、以下のことができるようになります:
- MavenベースのJavaプロジェクトに、Arquillianインフラストラクチャを追加する
- CDI beanの振る舞いを検証するArquillianのテストケースを書く
- 複数の互換性のあるコンテナでArquillianのテストケースを実行する
これらのスキルを、ArquillianをJava EEアプリケーションのテストスイートとMavenのビルドに組み込むことで学びます。このガイドは、読者がさっと始められるように、 速く読めるよう デザインされています!
前提
Arquillianを始める最も簡単なやり方は、依存性の管理をしているプロジェクトのテストスイートに組み込むことです。今日、このカテゴリで最も広く利用されているビルドツールは、 Apache Maven です。このガイドでは、サンプルのMavenプロジェクトを使って、最初の グリーンバー へ案内します。
ArquillianはMavenには、もっと言えばどんな特定のビルドツールにも依存しません。それはAntやGradleでビルドするプロジェクトで使っても—より優れているとは言わないまでも—同じように機能します。理想的には、ビルドツールは、 Maven Central repository で配布されているArquillianライブラリをプロジェクトに追加するタスクを単純化できる、依存性管理を提供している物がいいでしょう。
このガイドは、読者がコマンドシェルとIDE(Integrated Development Environment:統合開発環境)からMavenを利用できると仮定しています。もしそうでなければ、 Mavenをインストールしてください 。 また、 JDK 1.5 以降のインストールが必要です。
新しいプロジェクトを作成する
新しいプロジェクトを作成する際に、お勧めの方法が2つあります:
間違いなく、 JBoss Forge はより簡単なやり方ですが、このガイドではJBoss Forgeをまだ受け入れられないことを考慮して、両方のオプションを示します。上で示した二つのオプションからどちらかを選んで、次の説明に飛んでください。
既存のMavenプロジェクトがあれば、この章を、次章に進む前に正しい依存性の設定になっているかのレビューとして使うことができます。
Maven Archetypeからプロジェクトを生成する
まず、以下のコマンドでMavenベースのJavaプロジェクトを生成します。
$ mvn archetype:generate -DarchetypeGroupId=net.avh4.mvn.archetype \
-DarchetypeArtifactId=java-1.6-archetype
$ 以降のテキストをコピーして、コマンドシェルにペーストしてください。 プロンプトでは、それぞれ、コロン2つの後に示している値を入力してください。( <ENTER> で示しているように)各行でエンターキーを押してください。
Define value for property 'groupId': : org.arquillian.example <ENTER>
Define value for property 'artifactId': : arquillian-tutorial <ENTER>
Define value for property 'version': : <ENTER>
Define value for property 'package': : <ENTER>
Confirm properties configuration:
groupId: org.arquillian.example
artifactId: arquillian-tutorial
version: 1.0-SNAPSHOT
package: org.arquillian.example
Y: : <ENTER>
このコマンドは、カレントディレクトリに arquillian-tutorial という新しいフォルダを作り、そこにMavenベースのJavaプロジェクトを生成します。このプロジェクトのファイル構成は、次のようになります:
- src/
- main/
- java/ – アプリケーションのすべてのJavaソースファイルをここに置きます。(Javaパッケージの下に置きます)
- resources/ – アプリケーションの設定ファイルをここに置きます。
- test/
- java/ – すべてのテスト用のJavaソースコードをここに置きます。(Javaパッケージの下に置きます)
- resources/ – すべてのテスト用の設定ファイルをここに置きます。(例:arquillian.xml)
- main/
- pom.xml – Mavenのビルドファイルです。Mavenでどのようにプロジェクトをビルドするか定義します。
このプロジェクトは、Arquillianがそれぞれ最低限要求するバージョンであるJava 1.6とJUnit 4.8を使用するようにあらかじめ設定されています。
ジェネレータはまた、2つの java フォルダの下に、 org.arquillian.example というJavaパッケージを作成しています。 java フォルダ直下ではなく、このパッケージの下にJavaソースファイルを置いてください。
Arquillianはまた、TestNG 5をサポートしています。しかしこのガイドでは、JUnitを使用します。
さて、エディタで pom.xml を開いてください。XMLファイルには、基本的なプロジェクト情報、ビルドセクション、依存セクションが含まれているのが分かります。 JUnitより下の@
編集が終わったら、以下のようになっているはずです(表示上、簡潔にしてあります):
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion><groupId>org.arquillian.example</groupId> <artifactId>arquillian-tutorial</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging><name>arquillian-tutorial</name> <url>http://arquillian.org</url><properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties><build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>
これからJava EE 6コンポーネントを書きます。そのため、Java EE 6 APIをクラスパスに追加する必要があります。そうすれば、これらのコンポーネントをコンパイルできます。
pom.xml ファイルをもう一度開き、そのXMLフラグメントを <dependencies> 要素の下に追加してください。追加後は、以下のようになります:
<!-- clip -->
<dependencies>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- clip -->
Java EE APIアーティファクトを、 javax:javaee-api と組み合わせて 使わない ことを強くおすすめします。このバンドルは、メソッドの実装を省いたクラスが含まれているので、実行時に(テストの実行時でも)これがクラスパスに残っていた場合、アプリケーションは奇妙なAbsent Codeエラーを投げます。もっと背景を知りたい場合は、 このFAQを読んでください 。
プロジェクトの基本は準備できました! プロジェクトをEclipseで開く に進んでください。コードを書きはじめます!
Forgeでプロジェクトを生成する
JBoss Forge は、標準ベースの環境で高速アプリケーション開発をするためのコマンドシェルです。別の見方をすれば、ドーピングしたMaven Archetypeのようなものです。
Forgeのインストールは、比較的短い手順であり、このガイドでは、基礎を体験します。以下の、簡単なステップに従ってインストールしてください:
- Forgeをダウンロード し、ディスクに展開します。展開したフォルダを
$FORGE_HOMEと呼びます。
ホームディレクトリのforgeというフォルダに配布物を展開したと仮定します。 $FORGE_HOME/binを(WindowsやLinux、Mac OSXの)パスに追加します。
Unixベースのオペレーティングシステムでは、Forgeをパスに追加するというのは、一般的には、ユーザの$HOME/.bashrcまたは、$HOME/.profileを編集することになります。以下の環境変数をセットしてください:
$ export FORGE_HOME=$HOME/forge/
$ export PATH=$PATH:$FORGE_HOME/bin
Windowsでは、“コントロールパネル”を開き、右クリックして“システムのプロパティ”をクリックします。“詳細設定”タブを開き、“環境変数”をクリックします。そして、これらの二つのエントリを追加します。展開した配布物をすべてのユーザーがアクセスできる場所に置いていない限り、ユーザー変数にForgeを設定することをおすすめします。
これでForgeがインストール(つまり、展開)されたので、コマンドプロンプト(シェル)を開き、 forge コマンドを実行してください:
$ forge _____ | ___|__ _ __ __ _ ___ | |_ / _ \| `__/ _` |/ _ \ \\ | _| (_) | | | (_| | __/ // |_| \___/|_| \__, |\___| |___/[no project] ~ $
これだけです!Forgeが起動しました。さあ、プロジェクトを作る時です。
Forgeシェル上で、新しいプロジェクトを生成するために、以下のコマンドを実行してください。これは、上で、Maven Archetypeで作成したプロジェクトとそっくりです:
$ new-project --named arquillian-tutorial --topLevelPackage org.arquillian.example
このコマンドは、 arquillian-tutorial という MavenベースのJavaプロジェクトをカレントディレクトリの新規フォルダの下に生成します。
Forgeが生成したこのプロジェクトのファイル構成を以下に示します:
- src/
- main/
- java/ – アプリケーションのすべてのJavaソースファイルをここに置きます。(Javaパッケージの下に置きます)
- resources/ – アプリケーションの設定ファイルをここに置きます。
- META-INF/
- forge.xml – 空のForge設定ファイルです。
- META-INF/
- test/
- java/ – すべてのテスト用のJavaソースコードをここに置きます。(Javaパッケージの下に置きます)
- resources/ – すべてのテスト用の設定ファイルをここに置きます。(例:arquillian.xml)
- main/
- pom.xml – Mavenのビルドファイルです。Mavenでどのようにプロジェクトをビルドするか定義します。
また、ForgeはプロジェクトフォルダをForgeシェルのカレントディレクトリにします。
[arquillian-tutorial] arquillian-tutorial $
デフォルトでは、Forgeはプロジェクトに、Arquillianが最低限要求するバージョンである、Java 1.6を設定します。便利ですね。
次に追加する必要があるのは、Java EE APIです。以下の project add-dependency コマンドでできます:
$ project add-dependency org.jboss.spec:jboss-javaee-6.0:1.0.0.Final:pom:provided
また、Arquillianが最低限要求するバージョンである、JUnit 4.8をテストスコープの依存性として追加する必要があります:
$ project add-dependency junit:junit:4.8.1:test
Forgeが生成したpom.xmlを以下に示します:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="
http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.arquillian.example</groupId>
<artifactId>arquillian-tutorial</artifactId>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>provided</type>
<scope>pom</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>JBOSS_NEXUS</id>
<url>http://repository.jboss.org/nexus/content/groups/public</url>
</repository>
</repositories>
<build>
<finalName>arquillian-tutorial</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Arquillianは、Mavenセントラルリポジトリで配布されていて、そのためpom.xmlのJBossパブリックリポジトリの記述は不要で、削除できます。しかしMavenセントラルでは入手できない他のJBossソフトウェアを取得するために必要になるかもしれないことは、覚えておいてください。
もし、プロジェクトのpom.xmlにリポジトリを明記するのはアンチパターンだと考えるなら、settings.xmlでリポジトリをユーザーグローバルに友好にするために この説明 を読んでください。
プロジェクトの基本は準備できました!Eclipseでプロジェクトを開きましょう。コードを書きはじめます!
プロジェクトをEclipseで開く
Javaプロジェクトで開発するときは、EclipseのようなIDEを使うでしょう。だから、Arquillianは、IDEフレンドリーに設計されています。つまり、型破りな変更をしなくてもArquillianテストをIDEから実行できます。IDEの利点をすぐに活用しましょう。
Eclipseの起動から始めます。これはMavenプロジェクトなので、プロジェクトを開くには Maven Integration for Eclipse (m2e)のインストールが必要です。もしまだインストールしていなければ、簡単な方法は、 JBoss Tools をインストールすることです。次のステップに従ってEclipseマーケットプレイス(Eclipseのアプリケーションストアのようなもの)からインストールしてください。
- メインメニューから、
Help > Eclipse Marketplace...を選択 - 検索フィールドに"jboss tools"と入力し(引用符を除く)、Enterを押す
- JBoss Tools (Indigo)のインストールボタンをクリック
- インストールウィザードを完了して、再起動のプロンプトが表示されたら再起動する
JBoss Tools はJava EEアプリケーション開発の快適な環境を提供します。心配しないで、これはそんなに重いプラグインではありません。
しかし、余分なJBoss ToolsなしでMavenの統合をしたい場合は、下のステップに従ってください:
- メインメニューから、
Help > Eclipse Marketplace...を選択 - 検索フィールドに"maven"と入力し(引用符を除く)、Enterを押す
- Maven Integration for Eclipseのインストールボタンをクリック
- インストールウィザードを完了して、再起動のプロンプトが表示されたら再起動する
- Maven Integration for Eclipse WTPについてステップを繰り返す
Maven Integrationプラグインをインストールしたら、以下のステップでプロジェクトを開きます:
- メインメニューから、
File > Import...を選択 - input sourceフィールドで"existing maven"と入力する
- Existing Maven Projectsオプションを選択し、Nextボタンをクリックする
- Browse…ボタンをクリックする
- ファイルシステムでプロジェクトフォルダへ移動し、OKボタンをクリックする
- Finishボタンをクリックして、プロジェクトを開く
EclipseはMavenプロジェクトを認識し、プロジェクトナビゲータビューで開きます。プロジェクトを展開したら、次の画像と同様に見えるでしょう:

これで、ついに本題にたどり着きました!
コンポーネントを作る
Arquillianテストを書くために、テスト対象のコードが必要です。余計なものがないところでArquillianテストをどのように実行するか学ぶために、ビジネスコンポーネントの作成から始めましょう。だんだん複雑なシナリオに進みます。
IDEで、新しくJavaの Greeter クラスを org.arquillian.example パッケージに作成してください。内容を以下のように挨拶するロジックで置き換えてください:
package org.arquillian.example;import java.io.PrintStream;/** * A component for creating personal greetings. */ public class Greeter { public void greet(PrintStream to, String name) { to.println(createGreeting(name)); }public String createGreeting(String name) { return "Hello, " + name + "!"; } }
このクラスがCDI(Contexts and Dependency Injection) beanとして注入された際に、正しく振る舞うことを検証したいと考えています。もちろん、簡単にユニットテストを書くこともできます。しかしこのbeanは依存性注入やメッセージングのようなエンタープライズサービスを使用していて、コンテナ内で使用されなければならないということにしましょう(加えて、それに成長の機会を与えます
)。
このクラスをCDI beanとして使うために、 @Inject アノテーションでテストに注入します。これはArquillianテストを必要とします!つまり、Arquillian APIをプロジェクトに追加する時です!
Arquillian APIを追加する
もう一度、プロジェクト直下にある pom.xml をエディタで開きます。Mavenにどのバージョンのアーティファクトを使うかを示します。Arquillianの推移的な依存性のためのBOM(Bill of Materials)またはバージョンマトリックスをインポートするため、以下のXMLフラグメントを、 <build> 要素の上に追加してください。
<!-- clip -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.0.0.Final</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<!-- clip -->
次に、Arquillian-JUnitインテグレーションを加えるために、次のXMLフラグメントを最後の <dependency> 要素の下に追加してください:
<!-- clip -->
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<!-- clip -->
Arquillian-JUnitインテグレーションアーティファクトは、また、ShrinkWrap APIをテストクラスパスに追加します。これらの全ライブラリは、JUnit Arquillianテストを書き、コンパイルする際に必要です。
JUnitの代わりにTestNGを使うためには、Arquillian JUnitインテグレーションをArquillian TestNGインテグレーションで置き換えてください。
ここまでで、pom.xmlになにか問題があれば、 このgist からダウンロードできます。
最初のArquillianテストを書く準備ができました!
Arquillianテストを書く
Arquillianテストは、すこし余分なフレアのある、単なるユニットテストのように見えます。IDEに戻りましょう。
もし"Project configuration is out of date with pom.xml"というメッセージが表示されたら、プロジェクトを再同期するために右クリックしてProject > Maven > Update Project Configurationを選択してください.
src/test/javaにて、 org.arquillian.example パッケージ以下に GreeterTest という新しいJUnitテストケースを作成することから始めます。力仕事はほとんどArquillianがやるので、よくあるsetupとteardownメソッドは不要です。今のところ、次のようになります:
package org.arquillian.example;import org.junit.Assert; import org.junit.Test;public class GreeterTest { @Test public void should_create_greeting() { Assert.fail("Not yet implemented"); } }
では、フレアについてです。Arquillianテストケースは、以下の3点が必要です:
- クラスへの
@RunWith(Arquillian.class)アノテーションの付加 @Deploymentでアノテートされ、ShrinkWrapアーカイブを返すスタティックメソッド@Testでアノテートされた、少なくとも一つのメソッド
@RunWith アノテーションは、JUnitに、Arquillianをテストコントローラとして使用することを伝えます。Arquillianはテストアーカイブ(つまり、マイクロデプロイメント)を受け取るために @Deployment アノテーションのついたメソッドを探します。そしてマジックが起きて、それぞれの @Test メソッドはコンテナ環境内で実行されます。
テストアーカイブとは?
テストアーカイブの目的は、テストに必要なクラスとリソースを、クラスパスにあるそれ以外から隔離することです。通常のユニットテストとは異なり、Arquillianは単純にクラスパス上のすべてに手をつけることはしません。その代わり、テストに必要なもの(もしクラスパス上のすべてと決めれば、それかもしれません)だけを含めます。このアーカイブは、 ShrinkWrap を使って定義されます。これはアーカイブ(つまり、jar、war、ear)作成用のJava APIです。マイクロデプロイメントストラテジーにより、明確にテストしたいクラスにフォーカスできます。その結果として、テストは無駄のない状態のまま保たれます。
また、ShrinkWrapはアーティファクト(ライブラリ)の解決をサポートします。プログラム的に設定ファイルを作成し、テストアーカイブに追加します。ShrinkWrapのより詳細な説明は、 ShrinkWrap introduction を参照してください。
Arquillianのフレアをテストに加えましょう:
package org.arquillian.example;import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith;@RunWith(Arquillian.class) public class GreeterTest {@Deployment public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class) .addClass(Greeter.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); }@Test public void should_create_greeting() { Assert.fail("Not yet implemented"); } }
ShrinkWrapを使って、Javaアーカイブ(jar)を定義しました。このアーカイブは、テスト対象の Greeter クラスと、META-INFディレクトリ内にこのアーカイブでCDIを有効にするための空のbeans.xmlファイルを含みます。
ここでやるべきことは、テストメソッドの上で Greeter インスタンスを直接フィールドに注入し、未実装のテストメソッドをそのbeanの振る舞いを検証するものに置き換えることです。読者に和んでもらえるように、コンソールにも挨拶を出力します。
// clip import javax.inject.Inject; // clip@Inject Greeter greeter;@Test public void should_create_greeting() { Assert.assertEquals("Hello, Earthling!", greeter.createGreeting("Earthling")); greeter.greet(System.out, "Earthling"); }
編集が終わったらどのようにテストがどうなっているかというと:
package org.arquillian.example;import javax.inject.Inject; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.Test; import org.junit.Assert; import org.junit.runner.RunWith;@RunWith(Arquillian.class) public class GreeterTest {@Deployment public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class) .addClass(Greeter.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); }@Inject Greeter greeter;@Test public void should_create_greeting() { Assert.assertEquals("Hello, Earthling!", greeter.createGreeting("Earthling")); greeter.greet(System.out, "Earthling"); } }
最初のArquillianテストが書けました!
ああ、でもどのように動かすのか、疑問に思ってるかもしれませんね
“ユニットテストみたいに”と思っているなら、それは正解です!しかし、クラスパスにコンテナアダプタを追加する必要があります。
コンテナアダプタを追加する
これまで、コンテナでテストすることについて数多く語ってきましたが、今のところどれとは言及しませんでした。それは、実行時に決定することだからです。
Arquillianは、テストクラスパスで利用可能なコンテナの中からターゲットコンテナを選択します。だから、プロジェクトにもっとライブラリを追加します。
Arquillianのテストは、テストで使用するプログラミングモデルと互換性があるならば(コンテナ用のArquillianアダプタがあるならば)どんなコンテナでも実行できます。私達のテストは、CDIプログラミングモデルを使用しているので、CDIをサポートするコンテナを使う必要があります。開発中は高速にターンアラウンドしたいので、Weld EEエンベデッドコンテナから始めましょう。
また pom.xml を開き、他の <dependency> 要素の下に、 以下の依存性のグループを追加してください:
<!-- clip -->
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-weld-ee-embedded-1.1</artifactId>
<version>1.0.0.CR3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-core</artifactId>
<version>1.1.5.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
<!-- clip -->
まとめると、Arquillianを使うには、(JUnitと共に)以下の3つのライブラリが必要です:
- Arquillian JUnit インテグレーション
- ターゲットコンテナ向けのArquillianコンテナアダプタ
- コンテナのランタイム(エンベデッドコンテナ)または、コンテナのクライアント(リモートコンテナ)
このサンプルでは、エンベデッドコンテナを使っています。それで、コンテナのランタイムであるWeldが必要です。
さて、テストに戻ります。
Arquillianテストの実行
Arquillianに必要なすべてのライブラリをクラスパスに追加したら、ユニットテストのようにArquillianテストを実行できます。IDEから実行することも、ビルドスクリプトやどんなテストプラグインから実行することもできます。Eclipseから実行してみましょう。
IDEのウィンドウから、Package Explorer(またはエディタ)のGreeterTest.javaを右クリックしてコンテキストメニューからRun As > JUnit Testを選択します。

テストを実行したら、以下の行がコンソールに出力されるでしょう:
21 [main] INFO org.jboss.weld.Version - WELD-000900 1.1.5 (Final)
Hello, Earthling!
それから、JUnitビューが表示され、 グリーンバー が現れます!

コマンドラインから、Mavenでテストを実行することもできます:
$ mvn test
以下の行がコンソールに出力されるでしょう:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.arquillian.example.GreeterTest
19 [main] INFO org.jboss.weld.Version - WELD-000900 1.1.5 (Final)
Hello, Earthling!
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.907 sec
おめでとう! Arquillianを使って、最初の グリーンバー に到達しました!
詳しく見る
CDIが実際にはどのように動作しているかわかりますか?わかっていることは、Arquillianは、 Greeter クラスの新しいインスタンスを作成し、CDIとは無関係にテストに注入することだけです。そこを調べてみましょう。
org.arquillian.example パッケージに PhraseBuilder という新しいCDI beanを作成します。これは、テンプレートからフレーズを生成します。
package org.arquillian.example;import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; import javax.annotation.PostConstruct;public class PhraseBuilder { private Map<String, String> templates;public String buildPhrase(String id, Object... args) { return MessageFormat.format(templates.get(id), args); }@PostConstruct public void initialize() { templates = new HashMap<String, String>(); templates.put("hello", "Hello, {0}!"); } }
次に、 Greeter クラスを開き、コンストラクタインジェクションを使って PhraseBuilder を注入する、新しいコンストラクタを作成します。それから、挨拶を作るタスクを注入されたbeanに移譲します。
package org.arquillian.example;import java.io.PrintStream; import javax.inject.Inject;public class Greeter {private PhraseBuilder phraseBuilder;@Inject public Greeter(PhraseBuilder phraseBuilder) { this.phraseBuilder = phraseBuilder; }public void greet(PrintStream to, String name) { to.println(createGreeting(name)); }public String createGreeting(String name) { return phraseBuilder.buildPhrase("hello", name); } }
さて、テスト実行のために、 PhraseBuilder のインスタンスが作成され、 その @PostConstruct メソッドが実行され、 Greeter のインスタンスが作成されるときに Greeter のコンストラクタに注入されなければなりません。これらがすべてが起きれば、CDIが動作していることを確認できます。
最後のステップです。新しいクラスを作ったので、テスト時に @Deployment メソッド が返すアーカイブにそれを加える必要があります。簡単に、以下の行を変更してください:
.addClass(Greeter.class)
…次のように:
.addClasses(Greeter.class, PhraseBuilder.class)
もう一度テストを実行してください。また、 グリーンバー が表示されます!気持ちいいでしょう?
テストをデバッグする
これは短い章になるでしょう。なぜか?Arquillianのテストは、とても直接的なので、まさにユニットテストをデバッグするようにデバッグします。テストコードでも、アプリケーションコードでも、どこにでもブレークポイントを追加するだけです。それから、ファイルを右クリックして、Debug As > JUnit Testを選択します。これでコンテナでデバッグができます!楽しく調べ回ってください!

リモートコンテナを使っている場合、Debug As ではブレークポイントが有効になりません。その代わりに、コンテナをデバッグモードで起動して、デバッガをアタッチする必要があります。これは、テストが元々のテストランナーとは異なるJVM上で実行されているためです。
いま経験したように、ArquillianはCDIアプリケーションのテストには理想的なツールです。それはCDI環境のロードを行い、テストに直接、beanを注入します。もっとも良い点は、エンベデッドCDIコンテナを使っていると、ユニットテストのように素早く実行することです。これで要望が満たせたら、このチュートリアルを抜けてテストを書き始めてもかまいません。
しかし! エンベデッドコンテナはすべてのストーリーを語ってくれるでしょうか?コンポーネントは、完全なコンテナ上で実行しても動作するでしょうか?
Arquillianの恩恵の一つは、同じテストを互換性のある異なるコンテナ上で実行できることです。別のエンベデッドコンテナや、スタンドアロンのコンテナであっても。複数のコンテナを使いたいなら、読み進めてください。
さらにコンテナを追加する
以前に学んだように、Arquillianはクラスパス上のコンテナアダプタを元に、コンテナを選択します。別のコンテナに切り替えるには、クラスパス上のコンテナアダプタをテストの前に変更するだけです。
テスト実行の時点では、クラスパス上にコンテナアダプタは一つだけ存在できます。
クラスパス上のライブラリを切り替える一つの方法は、毎回手動で pom.xml に依存の定義を編集することです。でもそれは馬鹿馬鹿しい。もっといいやり方があります。
依存をグループに入れて区別するために、Mavenのプロファイルが使えます。コンテナアダプタと関連するアーティファクト毎に、一つのグループです。テスト実行時に、コマンドラインフラグ(-P)や、IDEのプリファレンスから、コンテナを選択するために一つのグループを有効化します。
pom.xml を開き、以下のXMLを <dependencies> 要素直下に追加して、Weld EEエンベデッド用の新しいプロファイルを作ります:
<!-- clip -->
<profiles>
<profile>
<id>arquillian-weld-ee-embedded</id>
<dependencies>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-weld-ee-embedded-1.1</artifactId>
<version>1.0.0.CR3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-core</artifactId>
<version>1.1.5.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>
<!-- clip -->
次に、 jboss-javaee-6.0 への依存とWeld EEエンベデッドコンテナアダプタへの依存をメインの <dependencies> セクションから 削除します 。編集後に、 <dependencies> と <profiles> セクションがどうなっているかを以下に示します:
<!-- clip -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>arquillian-weld-ee-embedded</id>
<dependencies>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-weld-ee-embedded-1.1</artifactId>
<version>1.0.0.CR3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-core</artifactId>
<version>1.1.5.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>
<!-- clip -->
エンベデッドGlassFishなどいくつかのコンテナは、Java EE APIを提供しているので、これらのライブラリへの依存はプロファイル以下に移動しました。同時に両方が同じクラスパス上にあると、コンフリクトを引き起こします。それで、このクラスパスのダンスをしなければなりません。
ここで2つのプロファイルを pom.xml の <profiles> 要素内に追加します。一つ目は、 Embedded GlassFish :
<!-- clip -->
<profile>
<id>arquillian-glassfish-embedded</id>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-glassfish-embedded-3.1</artifactId>
<version>1.0.0.CR2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.main.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.1.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
<!-- clip -->
もう一つは、JBoss AS マネージド:
<!-- clip -->
<profile>
<id>arquillian-jbossas-managed</id>
<dependencies>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-arquillian-container-managed</artifactId>
<version>7.1.1.Final</version>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
<!-- clip -->
これで、このテストは3つのコンテナの中から一つを選んで実行できるようになりました。
ここまでで、pom.xmlになにか問題があれば、 このgist からダウンロードできます。
コンテナを越えてテストする
Eclipseでプロジェクトをリフレッシュしたら、ビルドされないことに気づくでしょう。これは、コンテナプロファイルのどれかを有効にする必要があるからです。前の状態を復元するためにWeld EEエンベデッドプロファイルを有効にしましょう。
EclipseでMavenプロファイルを有効にするには、2つのやり方があります:
- 手動で設定(標準的なやり方)
- Maven profile selector (JBoss Tools)
有効なMavenプロファイルのセット:手動で設定
手動で有効なプロファイルをセットするには、以下のステップに従います:
- プロジェクトを右クリックして、Propertiesを選択する
- Maven propertiesを選択する
- Active Maven Profilesフィールドに、プロファイルIDを入力する(例えば、
arquillian-weld-ee-embedded) - OKボタンをクリックし、プロジェクトの変更を承諾する
以下が、プロファイルを有効にしたMaven properties画面です:

有効なMavenプロファイルのセット:Maven profile selector
JBoss Toolsがインストール済みなら、有効なプロファイルの選択はより簡単です:
- プロジェクトを右クリックし、 Maven > Select Active Profiles… を選択する
(あるいは、 Ctrl+Shift+P のキーバインディングか、ツールバーのボタンも使えます) - 有効化したいプロファイルの隣のチェックボックスをチェックする(例えば、
arquillian-weld-ee-embedded) - OKボタンをクリックする
次が、有効化したプロファイルを表示しているMaven profile selectorダイアログです:

一度プロファイルを有効化したら、テストはまた成功できるはずです。
すでにこのテストがWeld EEエンベデッドで成功することはわかっています。上のステップを繰り返してGlassFishエンベデッドに切り替え、今回は arquillian-glassfish-embedded だけを有効にします。テストをまた実行。GlassFishがコンソールで起動するのが見えて…今度も グリーンバー です!
これで、同じテストを異なる二つのエンベデッドコンテナで実行しました。CDIコンテナ(Weld)とJava EEコンテナ(GlassFish)です。どちらも実行はプロセス内です。純粋な環境でコンポーネントが正常に動作するか本当に確認するには、スタンドアロンのコンテナが必要です。JBoss ASを使うよう切り替えましょう。
スタンドアロンのJBoss ASインスタンスでテストするには、まず初めに次のどちらかのセットアップが必要です:
- ダウンロードしてプロジェクト外の場所に展開する または、
- ビルド中にMavenでダウンロード、展開することもできる
プロジェクト外でJBoss AS 7をセットアップするには、以下の手順に従ってください:
- JBoss AS 7をダウンロードする
(選んだバージョンが、pom.xmlの<artifactId>jboss-as-arquillian-container-managed</artifactId>で定義しているバージョンとあっていることを確認してください) - アーカイブを展開する
- (オプション)展開したディレクトリのパスを
JBOSS_HOME環境変数にセット
代わりに、Mavenにこのタスクを実行させるには、以下のXMLフラグメントを、 arquillian-jbossas-managed プロファイルの <id> 要素の下に追加してください:
<!-- clip -->
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>process-test-classes</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-dist</artifactId>
<version>7.1.1.Final</version>
<type>zip</type>
<overWrite>false</overWrite>
<outputDirectory>target</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<!-- clip -->
JBoss AS 7マネージドインスタンスをターゲットにするには、もう少しArquillianに設定が必要です。以下の設定ファイルを作成し、 jbossHome プロパティの値を、JBoss AS 7がインストールされた場所にします。Maven依存プラグインを使っている場合は、場所は、 target/jboss-as-7.1.1.Final です。
<arquillian xmlns="http://jboss.org/schema/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="jbossas-managed" default="true">
<configuration>
<property name="jbossHome">target/jboss-as-7.1.1.Final</property>
</configuration>
</container>
</arquillian>
さて、有効なMavenプロファイルを arquillian-jbossas-managed に変更して、またテストを実行します。コンソールでJBoss ASの起動が見えて…またもや グリーンバー です!
System.outに出力されたメッセージはコンソールではなくサーバーログに出力されます。
これは 同じ テストです。今回はスタンドアロンの(エンベデッドでない)Java EEコンテナで実行しました。Arquillianはテストをパッケージ化して、Java EEアーカイブとしてコンテナにデプロイし、リモートでテストを実行し、結果を取得したのち、EclipseのJUnitビュー(またはMavenのsurefire results)に伝えます。
Share the Knowledge
Find this guide useful?
There’s a lot more about Arquillian to cover. If you’re ready to learn more, check out the other available guides.
Feedback
Find a bug in the guide? Something missing? You can fix it by forking this website, making the correction and sending a pull request. If you’re just plain stuck, feel free to ask a question in the user discussion forum.
Recent Changelog
- Apr 30, 2012: Upgrade to jboss as 7.1.1.final by Dan Allen
- Apr 19, 2012: Remove redundant metadata (internal change) by Dan Allen
- Apr 13, 2012: Upgrade weld-ee-embedded adapter to 1.0.0.cr3 by Dan Allen
- Apr 10, 2012: Add javax.inject.inject import by Dan Allen
- Apr 10, 2012: Update first pom.xml listing, update download links, remove dead link and clarify java version by Dan Allen
- Apr 05, 2012: Add reference_rev prolog field for translations by Dan Allen
- Apr 05, 2012: Use description in prolog for guide summary by Dan Allen
- Mar 29, 2012: Updated the versions for weld and slf4j given in the pom files from 1.1.1.final and 1.5.10 to 1.1.5.final and 1.6.4 respectively by paul-thomson
- Mar 28, 2012: Use variable for arquillian core version by Dan Allen
- Mar 28, 2012: Fix bom version; add missing import for @inject by Craig Schwarzwald
- Mar 25, 2012: Escape stray inline xml tags by Dan Allen
- Mar 12, 2012: Update glassfish-embedded-all version and groupid by Dan Allen
- Feb 29, 2012: Remove extra whitespace by Dan Allen
- Feb 10, 2012: Identify authors & translators by site identity by Dan Allen
- Feb 09, 2012: Translate getting started guide to japanese by Takayuki Konishi










