1. 概要

Arquillian は、JakartaEE用のコンテナーに依存しない統合テストフレームワークです。 Arquillianを使用すると、コンテナ、デプロイメント、フレームワークの初期化などを管理する負担が最小限に抑えられます。

テスト環境のブートストラップではなく、実際のテストの作成に集中できます。

2. コアコンセプト

2.1. デプロイメントアーカイブ

コンテナ内で実行するときにアプリケーションをテストする簡単な方法があります。

まず、 ShrinkWrap クラスは、デプロイ可能な *。jar、 *。war、、および*。earファイルを作成するためのAPIを提供します。

次に、Arquillianでは、 @Deployment アノテーションを使用して、ShrinkWrapオブジェクトを返すメソッドでテストデプロイメントを構成できます。

2.2. コンテナ

Arquillianは、3つの異なるタイプのコンテナを区別します。

  • リモート–JMXなどのリモートプロトコルを使用してテスト済み
  • 管理対象–リモートコンテナですが、そのライフサイクルはArquillianによって管理されています
  • 埋め込み–ローカルプロトコルを使用してテストが実行されるローカルコンテナ

また、コンテナをその機能によって分類できます。

  • GlassfishやJBossなどのアプリケーションサーバーにデプロイされたJakartaEEアプリケーション
  • TomcatまたはJettyにデプロイされたサーブレットコンテナ
  • スタンドアロンコンテナ
  • OSGIコンテナー

ランタイムクラスパスを調べて、使用可能なコンテナを自動的に選択します。

2.3. テストエンリッチメント

Arquillianは、例えば テストを簡単に記述できるように、依存性注入。

@Inject を使用して依存性を注入したり、 @Resource を使用してリソースを注入したり、 @EJB、などを使用してEJBセッションBeanを注入したりできます。

2.4. 複数のテストランナー

アノテーションを使用して複数のデプロイメントを作成できます。

@Deployment(name="myname" order = 1)

ここで、nameはデプロイメントファイルの名前であり、orderパラメーターはデプロイメントの実行順序であるため、アノテーションを使用して複数のデプロイメントで同時にテストを実行できるようになりました。

@Test @OperateOnDeployment("myname")

beforeテストは、 @Deployment アノテーションで定義された順序を使用して、mynameデプロイメントコンテナーで実行されます。

2.5. Arquillian Extensions

Arquillianは、テストのニーズがコアランタイムでカバーされていない場合に備えて、複数の拡張機能を提供しています。 永続性、トランザクション、クライアント/サーバー、REST拡張機能などがあります。

MavenまたはGradleの構成ファイルに適切な依存関係を追加することで、これらの拡張機能を有効にできます。

一般的に使用される拡張機能は、ドローン、グラフェン、およびセレンです。

3. Mavenの依存関係とセットアップ

pom.xmlファイルに次の依存関係を追加しましょう。

<dependency>
    <groupId>org.jboss.arquillian</groupId>
    <artifactId>arquillian-bom</artifactId>
    <version>1.1.13.Final</version>
    <scope>import</scope>
    <type>pom</type>
</dependency>
<dependency>
    <groupId>org.glassfish.main.extras</groupId>
    <artifactId>glassfish-embedded-all</artifactId>
    <version>4.1.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.jboss.arquillian.container</groupId>
    <artifactId>arquillian-glassfish-embedded-3.1</artifactId>
    <version>1.0.0.Final</version>
    <scope>test</scope>
</dependency>

依存関係の最新バージョンは、 arquillian-bom org.glassfish.main.extras org.jboss.arquillian.containerにあります。

4. 簡単なテスト

4.1. コンポーネントを作成する

簡単なコンポーネントから始めましょう。 テストに集中できるようにするための高度なロジックはここには含まれていません。

public class Component {
    public void sendMessage(PrintStream to, String msg) {
        to.println(message(msg));
    }

    public String message(String msg) {
        return "Message, " + msg;
    }
}

Arquillianを使用して、このクラスがCDIBeanとして呼び出されたときに正しく動作することをテストします。

4.2. 私たちの最初のArquillianテストを書く

まず、フレームワーク固有のランナーを使用してテストクラスを実行するように指定する必要があります。

@RunWith(Arquillian.class)

コンテナー内でテストを実行する場合は、@Deploymentアノテーションを使用する必要があります。

Arquillianは、テストアーカイブを分離するためにクラスパス全体を使用するわけではありません。 代わりに、アーカイブを作成するためのJavaAPIであるShrinkWrapクラスを使用します。 テストするアーカイブを作成するときに、テストを使用するためにクラスパスに含めるファイルを指定します。 展開中、 ShrinkWrap は、テストに必要なクラスのみを分離します。

addclass()メソッドを使用して、必要なすべてのクラスを指定し、空のマニフェストリソースを追加することもできます。

JavaArchive.class は、 test.warというモックアップWebアーカイブを作成します。このファイルはコンテナーにデプロイされ、Arquillianがテストを実行するために使用します。

@Deployment
public static JavaArchive createDeployment() {
    return ShrinkWrap.create(JavaArchive.class)
      .addClass(Component.class)
      .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}

次に、コンポーネントをテストに注入します。

@Inject
private Component component;

最後に、テストを実行します。

assertEquals("Message, MESSAGE",component.message(("MESSAGE")));
 
component.sendMessage(System.out, "MESSAGE");

5. EnterpriseJavaBeansのテスト

5.1. エンタープライズJavaBean

Arquillianを使用すると、Enterprise Java Beanの依存性注入をテストできます。これを行うには、任意の単語を小文字に変換するメソッドを持つクラスを作成します。

public class ConvertToLowerCase {
    public String convert(String word){
        return word.toLowerCase();
    }
}

このクラスを使用して、前に作成したメソッドを呼び出すためのステートレスクラスを作成します。

@Stateless
public class CapsConvertor {
    public ConvertToLowerCase getLowerCase(){
        return new ConvertToLowerCase();
    }
}

CapsConvertorクラスがサービスBeanに挿入されます。

@Stateless
public class CapsService {
 
    @Inject
    private CapsConvertor capsConvertor;
    
    public String getConvertedCaps(final String word){
        return capsConvertor.getLowerCase().convert(word);
    }
}

5.2. EnterpriseJavaBeanをテストします

これで、Arquillianを使用してエンタープライズJava Beanをテストし、CapsServiceを挿入できます。

@Inject
private CapsService capsService;
    
@Test
public void givenWord_WhenUppercase_ThenLowercase(){
    assertTrue("capitalize".equals(capsService.getConvertedCaps("CAPITALIZE")));
    assertEquals("capitalize", capsService.getConvertedCaps("CAPITALIZE"));
}

ShrinkWrapを使用して、すべてのクラスが正しく配線されていることを確認します。

@Deployment
public static JavaArchive createDeployment() {
    return ShrinkWrap.create(JavaArchive.class)
      .addClasses(CapsService.class, CapsConvertor.class, ConvertToLowerCase.class)
      .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}

6. JPAのテスト

6.1. 永続性

Arquillianを使用して永続性をテストすることもできます。 まず、エンティティを作成します。

@Entity
public class Car {
 
    @Id
    @GeneratedValue
    private Long id;
 
    @NotNull
    private String name;

    // getters and setters
}

車の名前を保持するテーブルがあります。

次に、EJBを作成して、データに対して基本的な操作を実行します。

@Stateless
public class CarEJB {
 
    @PersistenceContext(unitName = "defaultPersistenceUnit")
    private EntityManager em;
 
    public Car saveCar(Car car) {
        em.persist(car);
        return car;
    }
 
    public List<Car> findAllCars() {
    Query query 
      = em.createQuery("SELECT b FROM Car b ORDER BY b.name ASC");
    List<Car> entries = query.getResultList();
    
    return entries == null ? new ArrayList<>() : entries;    
 
    public void deleteCar(Car car) {
        car = em.merge(car);
        em.remove(car);
    }
}

saveCar を使用すると、車の名前をデータベースに保存できます。また、 findAllCars、を使用してすべての車を保存できます。また、deleteCarを使用してデータベースから車を削除できます。 ]。

6.2. Arquillianで永続性をテストする

これで、Arquillianを使用していくつかの基本的なテストを実行できます。

まず、クラスを ShrinkWrap:に追加します

.addClasses(Car.class, CarEJB.class)
.addAsResource("META-INF/persistence.xml")

次に、テストを作成します。

@Test
public void testCars() {
    assertTrue(carEJB.findAllCars().isEmpty());
    Car c1 = new Car();
    c1.setName("Impala");
    Car c2 = new Car();
    c2.setName("Lincoln");
    carEJB.saveCar(c1);
    carEJB.saveCar(c2);
 
    assertEquals(2, carEJB.findAllCars().size());
 
    carEJB.deleteCar(c1);
 
    assertEquals(1, carEJB.findAllCars().size());
}

このテストでは、最初に4つの車のインスタンスを作成し、データベースの行数が作成したものと同じであることを確認します。

8. 結論

このチュートリアルでは、次のことを行います。

  • Arquillianコアコンセプトを導入
  • Arquillianテストにコンポーネントを注入しました
  • EJBをテストしました
  • テストされた永続性
  • Mavenを使用してArquillianテストを実行しました

コードは、Githubの記事から見つけることができます。