CLOVER🍀

That was when it all began.

WildFly 33+WildFly Glow+Arquillianでテストを書いてみる(Bootable JAR/Managed、オマケでRemote)

これは、なにをしたくて書いたもの?

最近はWildFlyを使うのにWildFly Glow(WildFly Maven Plugin経由で)使うことが多いのですが、WildFly GlowとArquillianを組み合わせて
使ってみたいなと思いまして。

この組み合わせでテストを動かしてみることにしました。

WildFly Glow Arquillian Maven Plugin

WildFly GlowとArquillianを組み合わせるには、WildFly Glow Arquillian Maven Pluginが必要です。

WildFly Glow Arquillian Maven Pluginを紹介しているブログエントリーはこちら。

WildFly testing with WildFly Glow

WildFly Glowは、WildFlyのプロビジョニングツールであるGalleonを簡単に扱えるようにしたものです。

WildFly Glow, an evolution of WildFly provisioning

WildFly Glow Arquillian Maven Pluginを使うと、テスト実行前にGalleonレイヤーをスキャンできます。

こんな感じの動作をするようです。

  • テストクラスの@Deploymentアノテーションが付与されたstaticメソッドをスキャンして、必要なGalleonレイヤーを検出する
  • 検出したレイヤーやFeature Packを含んだprovisioning.xmlを生成する

The WildFly Glow Arquillian Maven plugin scans all the @Deployment annotated static methods, and invokes them to obtain each deployment. It then scans these deployments to discover the required Galleon layers.

A provisioning.xml file containing the discovered layers and feature-packs is generated. This Galleon configuration file is then used by the actual provisioning tooling (Galleon Maven Plugin, WildFly Maven Plugin, WildFly JAR Maven Plugin) to provision the test server.

WildFly testing with WildFly Glow

そして、WildFly Glow Arquillian Maven Pluginによって生成されたprovisioning.xmlをプロビジョニングツール(WildFly Maven Pluginなど)に
渡して、テスト用のサーバーをプロビジョニングします。

つまり、プロビジョニングツール(WildFly Maven Pluginなど)よりも前にWildFly Glow Arquillian Maven Pluginは動作することになります。
また、名前の割にArquillian自体は出てこなさそうですね。

WildFly Glow Arquillian Maven Pluginでは、検出したレイヤーなどが期待どおりであるか検証する機能も持っているようです。

In order to validate that what the scanning has discovered is what you are expecting, you can configure the wildfly-glow-arquillian-plugin maven plugin to contain the element <expected-discovery>.

WildFly Glowのドキュメントはこちら。

WildFly Glow Documentation

WildFly Glow Arquillian Maven Pluginに関する部分はこちらです。

WildFly Glow Documentation / WildFly Glow Arquillian Maven plugin

今回のエントリーを書くにあたっては、これらのドキュメントの他にこちらのWildFlyのテストを参考にしています。

https://github.com/wildfly/wildfly/tree/33.0.2.Final/testsuite/integration/web

お題

今回のお題は、以前に書いたこちらのエントリーをWildFly Glowを使ってテストを実行できるように書き直したいと思います。

WildFly 31+Arquillian+JUnit 5でインテグレーションテスト(Managed/Remote/Bootable JAR) - CLOVER🍀

対象はBootable JARとManagedです。RemoteはWildFly Glow Arquillian Maven Pluginが出てこなくなりますが、今回はオマケ的につけて
おくことにします。

また、テストはインテグレーションテストではなくて単体テストにすることにします。

環境

今回の環境はこちら。

$ java --version
openjdk 21.0.4 2024-07-16
OpenJDK Runtime Environment (build 21.0.4+7-Ubuntu-1ubuntu222.04)
OpenJDK 64-Bit Server VM (build 21.0.4+7-Ubuntu-1ubuntu222.04, mixed mode, sharing)


$ mvn --version
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 21.0.4, vendor: Ubuntu, runtime: /usr/lib/jvm/java-21-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "5.15.0-122-generic", arch: "amd64", family: "unix"

テスト対象プログラムの作成

まずは、テスト対象のプログラムを作成します。 Jakarta RESTful Web Services(JAX-RS)とJakarta Contexts and Dependency Injection(CDI)を使った簡単なプログラムにします。

pom.xmlから載せていきます。

pom.xml

<?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.littlewings</groupId>
    <artifactId>wildfly-glow-arquillian-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.release>21</maven.compiler.release>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.wildfly.bom</groupId>
                <artifactId>wildfly-ee-with-tools</artifactId>
                <version>33.0.2.Final</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.junit</groupId>
                <artifactId>junit-bom</artifactId>
                <version>5.11.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>jakarta.ws.rs</groupId>
            <artifactId>jakarta.ws.rs-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jakarta.enterprise</groupId>
            <artifactId>jakarta.enterprise.cdi-api</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.arquillian.junit5</groupId>
            <artifactId>arquillian-junit5-container</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.26.3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <version>5.5.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.18.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>ROOT</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.4.0</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <profiles>
    〜あとで〜
    </profiles>
</project>

必要な依存関係の管理は、ある程度はBOMで行うことにしました。

WildFly Arquillian Adapter(wildfly-arquillian-container〜)が足りないのですが、それはProfileで追加していくことにします。

Profileは、Arquillianでテストするバリエーション(Bootable JAR、Managed、Remote)だけ用意します。

    <profiles>
    〜あとで〜
    </profiles>

JAX-RSの有効化。

src/main/java/org/littlewings/wildfly/arquillian/RestApplication.java

package org.littlewings.wildfly.arquillian;

import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;

@ApplicationPath("/")
public class RestApplication extends Application {
}

JAX-RSリソースクラス。

src/main/java/org/littlewings/wildfly/arquillian/EchoResource.java

package org.littlewings.wildfly.arquillian;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;

import java.util.Map;

@Path("/echo")
@ApplicationScoped
public class EchoResource {
    @Inject
    private MessageService messageService;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String get(@QueryParam("message") String message) {
        return messageService.format(message);
    }

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public Map<String, Object> post(Map<String, Object> request) {
        return Map.of("message", messageService.format((String) request.get("message")));
    }
}

CDI管理Bean。

src/main/java/org/littlewings/wildfly/arquillian/MessageService.java

package org.littlewings.wildfly.arquillian;

import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class MessageService {
    public String format(String message) {
        return String.format("★★★ %s ★★★", message);
    }
}

動作イメージはこんな感じです。

$ curl localhost:8080/echo?message=Hello+World
★★★ Hello World ★★★


$ curl -XPOST -H 'Content-Type: application/json' localhost:8080/echo -d '{"message": "Hello World"}'
{"message":"★★★ Hello World ★★★"}

テストコードはこちら。CDI管理Beanのテストと、クライアント側のテストが含まれています。

src/test/java/org/littlewings/wildfly/arquillian/WildFlyArquillianTest.java

package org.littlewings.wildfly.arquillian;

import io.restassured.http.ContentType;
import jakarta.inject.Inject;
import jakarta.ws.rs.ApplicationPath;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit5.ArquillianExtension;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.modules.maven.ArtifactCoordinates;
import org.jboss.modules.maven.MavenResolver;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import java.io.IOException;
import java.net.URL;
import java.util.Map;

import static io.restassured.RestAssured.given;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.is;

@ExtendWith(ArquillianExtension.class)
class WildFlyArquillianTest {
    @Deployment
    static WebArchive createDeployment() throws IOException {
        return ShrinkWrap
                .create(WebArchive.class)
                .addPackages(true, RestApplication.class.getPackage())
                .addAsLibraries(
                        MavenResolver
                                .createDefaultResolver()
                                .resolveJarArtifact(ArtifactCoordinates.fromString("org.assertj:assertj-core:3.26.3"))
                );
    }

    @Inject
    MessageService messageService;

    @Test
    void cdiBeanTest() {
        assertThat(messageService.format("Hello World"))
                .isEqualTo("★★★ Hello World ★★★");
    }

    @ArquillianResource
    private URL deploymentUrl;

    String resourcePrefix =
            RestApplication.class
                    .getAnnotation(ApplicationPath.class)
                    .value()
                    .replaceFirst("^/", "");

    @Test
    @RunAsClient
    void jaxrsResourceTest() {
        given()
                .queryParam("message", "Hello World")
                .when()
                .get(String.format("%s%s%s", deploymentUrl, resourcePrefix, "echo"))
                .then()
                .assertThat()
                .statusCode(200)
                .body(is("★★★ Hello World ★★★"));

        given()
                .contentType(ContentType.JSON)
                .body(Map.of("message", "Hello World"))
                .when()
                .post(String.format("%s%s%s", deploymentUrl, resourcePrefix, "echo"))
                .then()
                .assertThat()
                .statusCode(200)
                .body("message", is("★★★ Hello World ★★★"));
    }
}

@Deploymentはこちら。これがWildFly Glow Arquillian Maven Pluginでスキャンされることになります。

    @Deployment
    static WebArchive createDeployment() throws IOException {
        return ShrinkWrap
                .create(WebArchive.class)
                .addPackages(true, RestApplication.class.getPackage())
                .addAsLibraries(
                        MavenResolver
                                .createDefaultResolver()
                                .resolveJarArtifact(ArtifactCoordinates.fromString("org.assertj:assertj-core:3.26.3"))
                );
    }

WildFly Arquillian Adapterを組み込んでテストを実行する

それでは、ここまで用意したソースコードおよびテストコードを使って、Arquillianを動かしてテストを実行していきます。

Arquillianの設定ファイルを用意する

まずはArquillianの設定ファイルを用意します。Bootable JAR、Managed、そしてRemote向けの設定ファイルで管理することにして、
システムプロパティarquillian.launchでどの設定を使うかを切り替えます。

src/test/resources/arquillian.xml

<?xml version="1.0" encoding="UTF-8" ?>
<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="wildfly-bootable" default="true">
        <configuration>
            <property name="jarFile">${bootable.jar}</property>
        </configuration>
    </container>

    <container qualifier="wildfly-managed">
        <configuration>
            <property name="jbossHome">${provisioned.wildfly.home}</property>
        </configuration>
    </container>

    <container qualifier="wildfly-remote">
    </container>
</arquillian>

arquillian.launchについてはこちらを参照。

Container config runtime selection - Arquillian

wildfly-bootableはBootable JAR向け、wildfly-managedはManaged向け、wildfly-remoteはRemote向けということで用意しています。

Bootable JAR

最初はBootable JAR向けの設定から書いていきましょう。ここから先は、用意したMavenのProfileを紹介していく形式になります。

        <profile>
            <id>bootable</id>

            <properties>
                <skipTests>false</skipTests>
            </properties>

            <dependencies>
                <dependency>
                    <groupId>org.wildfly.arquillian</groupId>
                    <artifactId>wildfly-arquillian-container-bootable</artifactId>
                    <version>5.1.0.Beta4</version> <!-- wildfly-ee-with-toolsに入っていない -->
                    <scope>test</scope>
                    <exclusions>
                        <exclusion>
                            <!-- arquillian-protocol-servlet-jakarta 1.9.1.Finalはない… -->
                            <groupId>org.jboss.arquillian.protocol</groupId>
                            <artifactId>arquillian-protocol-servlet-jakarta</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
                <dependency>
                    <groupId>org.jboss.arquillian.protocol</groupId>
                    <artifactId>arquillian-protocol-servlet-jakarta</artifactId>
                    <version>10.0.0.Final</version>
                    <scope>test</scope>
                </dependency>
            </dependencies>

            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <version>3.5.1</version>
                        <configuration>
                            <systemPropertyVariables>
                                <arquillian.launch>wildfly-bootable</arquillian.launch>
                                <bootable.jar>${basedir}/target/test-bootable.jar</bootable.jar>
                            </systemPropertyVariables>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.wildfly.plugins</groupId>
                        <artifactId>wildfly-maven-plugin</artifactId>
                        <version>5.0.1.Final</version>
                        <executions>
                            <execution>
                                <id>package</id>
                                <goals>
                                    <goal>package</goal>
                                </goals>
                                <configuration>
                                    <bootable-jar>true</bootable-jar>
                                    <bootable-jar-name>${project.artifactId}-${project.version}-server-bootable.jar</bootable-jar-name>
                                    <overwrite-provisioned-server>true</overwrite-provisioned-server>
                                    <discover-provisioning-info>
                                        <version>33.0.2.Final</version>
                                    </discover-provisioning-info>
                                </configuration>
                            </execution>
                            <execution>
                                <id>test-provisioning</id>
                                <goals>
                                    <goal>package</goal>
                                </goals>
                                <phase>process-test-classes</phase>
                                <configuration>
                                    <provisioning-dir>${project.build.directory}/wildfly-arquillian-bootable</provisioning-dir>
                                    <provisioning-file>${project.build.directory}/glow-scan/provisioning.xml</provisioning-file>
                                    <bootable-jar>true</bootable-jar>
                                    <bootable-jar-name>test-bootable.jar</bootable-jar-name>
                                    <skipDeployment>true</skipDeployment>
                                    <skip>${skipTests}</skip>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>org.wildfly.glow</groupId>
                        <artifactId>wildfly-glow-arquillian-plugin</artifactId>
                        <version>1.1.0.Final</version>
                        <executions>
                            <execution>
                                <id>scan</id>
                                <goals>
                                    <goal>scan</goal>
                                </goals>
                                <phase>test-compile</phase>
                            </execution>
                        </executions>
                        <configuration>
                            <expected-discovery>[cdi, datasources, jaxrs]==>ee-core-profile-server,datasources,jaxrs</expected-discovery>
                            <server-version>33.0.2.Final</server-version>
                            <skip-scanning>${skipTests}</skip-scanning>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

依存関係にWildFly Arquillian Adapterを加えます。

            <dependencies>
                <dependency>
                    <groupId>org.wildfly.arquillian</groupId>
                    <artifactId>wildfly-arquillian-container-bootable</artifactId>
                    <version>5.1.0.Beta4</version> <!-- wildfly-ee-with-toolsに入っていない -->
                    <scope>test</scope>
                    <exclusions>
                        <exclusion>
                            <!-- arquillian-protocol-servlet-jakarta 1.9.1.Finalはない… -->
                            <groupId>org.jboss.arquillian.protocol</groupId>
                            <artifactId>arquillian-protocol-servlet-jakarta</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
                <dependency>
                    <groupId>org.jboss.arquillian.protocol</groupId>
                    <artifactId>arquillian-protocol-servlet-jakarta</artifactId>
                    <version>10.0.0.Final</version>
                    <scope>test</scope>
                </dependency>
            </dependencies>

なのですが、wildfly-arquillian-container-bootablewildfly-ee-with-toolsに含まれていなかったので、自分でバージョンを指定することに
なりました。

また、wildfly-arquillian-container-bootablearquillian-protocol-servlet-jakartaの1.9.1.Finalを要求するのですが、そのバージョンはないようです。
実際には10.0.0.Finalが適切なようなのでexcludeして自分で追加…。

GitHub - arquillian/arquillian-jakarta

この依存関係の調整は以降のWildFly Arquillian Adapterすべてで同じことをすることになります。

Mavenプラグインの説明に移ります。

話が簡単なMaven Surefire Pluginから。システムプロパティで、Bootable JAR向けに用意したArquillianの設定を使うように指定しています。
また、テストで使うBootable JARを指定しています。

                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <version>3.5.1</version>
                        <configuration>
                            <systemPropertyVariables>
                                <arquillian.launch>wildfly-bootable</arquillian.launch>
                                <bootable.jar>${basedir}/target/test-bootable.jar</bootable.jar>
                            </systemPropertyVariables>
                        </configuration>
                    </plugin>

対応するArquillianの設定はこちらですね。

    <container qualifier="wildfly-bootable" default="true">
        <configuration>
            <property name="jarFile">${bootable.jar}</property>
        </configuration>
    </container>

WildFly Maven Plugin。wildfly:package向けの設定を2つ書いています。ここではBootable JARを作成します。

                    <plugin>
                        <groupId>org.wildfly.plugins</groupId>
                        <artifactId>wildfly-maven-plugin</artifactId>
                        <version>5.0.1.Final</version>
                        <executions>
                            <execution>
                                <id>package</id>
                                <goals>
                                    <goal>package</goal>
                                </goals>
                                <configuration>
                                    <bootable-jar>true</bootable-jar>
                                    <bootable-jar-name>${project.artifactId}-${project.version}-server-bootable.jar</bootable-jar-name>
                                    <overwrite-provisioned-server>true</overwrite-provisioned-server>
                                    <discover-provisioning-info>
                                        <version>33.0.2.Final</version>
                                    </discover-provisioning-info>
                                </configuration>
                            </execution>
                            <execution>
                                <id>test-provisioning</id>
                                <goals>
                                    <goal>package</goal>
                                </goals>
                                <phase>process-test-classes</phase>
                                <configuration>
                                    <provisioning-dir>${project.build.directory}/wildfly-arquillian-bootable</provisioning-dir>
                                    <provisioning-file>${project.build.directory}/glow-scan/provisioning.xml</provisioning-file>
                                    <bootable-jar>true</bootable-jar>
                                    <bootable-jar-name>test-bootable.jar</bootable-jar-name>
                                    <skipDeployment>true</skipDeployment>
                                    <skip>${skipTests}</skip>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>

こちらがArquillianで使うテスト向けの設定ですね。

                            <execution>
                                <id>test-provisioning</id>
                                <goals>
                                    <goal>package</goal>
                                </goals>
                                <phase>process-test-classes</phase>
                                <configuration>
                                    <provisioning-dir>${project.build.directory}/wildfly-arquillian-bootable</provisioning-dir>
                                    <provisioning-file>${project.build.directory}/glow-scan/provisioning.xml</provisioning-file>
                                    <bootable-jar>true</bootable-jar>
                                    <bootable-jar-name>test-bootable.jar</bootable-jar-name>
                                    <skipDeployment>true</skipDeployment>
                                    <skip>${skipTests}</skip>
                                </configuration>
                            </execution>

provisioning-dirは本物のパッケージングと被らないように、別のディレクトリを指定。provisioning-fileWildFly Glow Arquillian Maven Pluginが
出力するprovisioning.xmlを指定しています。

Bootable JARを作成するようにはしていますが、JARファイル名はテスト用のものにしているのと、プロジェクトのアーティファクト(要するに
WARファイル)はデプロイしないようにしています。デプロイするのは、Arquillianでのテストで使うものだけにします。

なお、この使い方をする場合はprocess-test-classesフェーズに仕込むことになります。

                    <plugin>
                        <groupId>org.wildfly.glow</groupId>
                        <artifactId>wildfly-glow-arquillian-plugin</artifactId>
                        <version>1.1.0.Final</version>
                        <executions>
                            <execution>
                                <id>scan</id>
                                <goals>
                                    <goal>scan</goal>
                                </goals>
                                <phase>test-compile</phase>
                            </execution>
                        </executions>
                        <configuration>
                            <expected-discovery>[cdi, datasources, jaxrs]==>ee-core-profile-server,datasources,jaxrs</expected-discovery>
                            <server-version>33.0.2.Final</server-version>
                            <skip-scanning>${skipTests}</skip-scanning>
                        </configuration>
                    </plugin>

WildFly Glow Arquillian Maven Plugin。こちらがテスト用のWildFly Maven Pluginのプロビジョニングよりも先に動くことになります。

                    <plugin>
                        <groupId>org.wildfly.glow</groupId>
                        <artifactId>wildfly-glow-arquillian-plugin</artifactId>
                        <version>1.1.0.Final</version>
                        <executions>
                            <execution>
                                <id>scan</id>
                                <goals>
                                    <goal>scan</goal>
                                </goals>
                                <phase>test-compile</phase>
                            </execution>
                        </executions>
                        <configuration>
                            <expected-discovery>[cdi, datasources, jaxrs]==>ee-core-profile-server,datasources,jaxrs</expected-discovery>
                            <server-version>33.0.2.Final</server-version>
                            <skip-scanning>${skipTests}</skip-scanning>
                        </configuration>
                    </plugin>

expected-discoveryで期待する検出結果を指定しています。server-versionは使用するWildFlyのバージョンですね。指定しない場合は
最新の安定版を基準に動作するようです。

蛇足ですが、-DskipTests=trueを指定した時にはWildFly Glow Arquillian Maven Pluginの実行はスキップするように設定しています。
この時はテスト用のプロビジョニングもスキップするように設定しています。

テストを実行してみます。

$ mvn -P bootable test

WildFly Glow Arquillian Maven Pluginによるスキャンの結果は以下のように表示されます。

[INFO] --- wildfly-glow-arquillian:1.1.0.Final:scan (scan) @ wildfly-glow-arquillian-example ---
Starting Scanner in forked process
[INFO] [cdi, datasources, jaxrs]==>ee-core-profile-server,datasources,jaxrs
[INFO]

これとexpected-discoveryで指定した値が一致しなかった場合は、ビルドに失敗します。

テストは問題なく完了です。

[INFO] Results:
[INFO]
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO]

以下のコマンドでは、テスト用のプロビジョニングを行ってテストを実行した後に、本来のパッケージングを行います。

$ mvn -P bootable package

パッケージングされたBootable JARを実行。

$ java -jar target/wildfly-glow-arquillian-example-0.0.1-SNAPSHOT-server-bootable.jar

テストをスキップする場合はこちら。

$ mvn -P bootable package -DskipTests=true

ここで、WildFly Maven PluginおよびWildFly Glow Arquillian Maven Pluginをスキップするように設定していないと、テストはスキップする割に
テスト向けのレイヤーのスキャンやプロビジョニングはしっかり実行するので、時間が余計にかかります…。

Managed

続いてはManagedです。WildFly Glow Arquillian Maven Pluginを使うのはここまでだったりします。

        <profile>
            <id>managed</id>

            <properties>
                <skipTests>false</skipTests>
            </properties>

            <dependencies>
                <dependency>
                    <groupId>org.wildfly.arquillian</groupId>
                    <artifactId>wildfly-arquillian-container-managed</artifactId>
                    <scope>test</scope>
                    <exclusions>
                        <exclusion>
                            <!-- arquillian-protocol-servlet-jakarta 1.9.1.Finalはない… -->
                            <groupId>org.jboss.arquillian.protocol</groupId>
                            <artifactId>arquillian-protocol-servlet-jakarta</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
                <dependency>
                    <groupId>org.jboss.arquillian.protocol</groupId>
                    <artifactId>arquillian-protocol-servlet-jakarta</artifactId>
                    <version>10.0.0.Final</version>
                    <scope>test</scope>
                </dependency>
            </dependencies>

            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <version>3.5.1</version>
                        <configuration>
                            <systemPropertyVariables>
                                <arquillian.launch>wildfly-managed</arquillian.launch>
                                <provisioned.wildfly.home>${project.build.directory}/wildfly-arquillian-managed</provisioned.wildfly.home>
                            </systemPropertyVariables>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.wildfly.plugins</groupId>
                        <artifactId>wildfly-maven-plugin</artifactId>
                        <version>5.0.1.Final</version>
                        <executions>
                            <execution>
                                <id>package</id>
                                <goals>
                                    <goal>package</goal>
                                </goals>
                                <configuration>
                                    <overwrite-provisioned-server>true</overwrite-provisioned-server>
                                    <discover-provisioning-info>
                                        <version>33.0.2.Final</version>
                                    </discover-provisioning-info>
                                </configuration>
                            </execution>
                            <execution>
                                <id>test-provisioning</id>
                                <goals>
                                    <goal>provision</goal>
                                </goals>
                                <phase>process-test-classes</phase>
                                <configuration>
                                    <provisioning-dir>${project.build.directory}/wildfly-arquillian-managed</provisioning-dir>
                                    <provisioning-file>${project.build.directory}/glow-scan/provisioning.xml</provisioning-file>
                                    <skip>${skipTests}</skip>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>org.wildfly.glow</groupId>
                        <artifactId>wildfly-glow-arquillian-plugin</artifactId>
                        <version>1.1.0.Final</version>
                        <executions>
                            <execution>
                                <id>scan</id>
                                <goals>
                                    <goal>scan</goal>
                                </goals>
                                <phase>test-compile</phase>
                            </execution>
                        </executions>
                        <configuration>
                            <expected-discovery>[cdi, datasources, jaxrs]==>ee-core-profile-server,datasources,jaxrs</expected-discovery>
                            <server-version>33.0.2.Final</server-version>
                            <skip-scanning>${skipTests}</skip-scanning>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

wildfly-arquillian-container-managedwildfly-ee-with-toolsに含まれているので、バージョンを明示する必要はありません。
arquillian-protocol-servlet-jakartaのバージョン指定がおかしいところは変わりませんが…。

            <dependencies>
                <dependency>
                    <groupId>org.wildfly.arquillian</groupId>
                    <artifactId>wildfly-arquillian-container-managed</artifactId>
                    <scope>test</scope>
                    <exclusions>
                        <exclusion>
                            <!-- arquillian-protocol-servlet-jakarta 1.9.1.Finalはない… -->
                            <groupId>org.jboss.arquillian.protocol</groupId>
                            <artifactId>arquillian-protocol-servlet-jakarta</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
                <dependency>
                    <groupId>org.jboss.arquillian.protocol</groupId>
                    <artifactId>arquillian-protocol-servlet-jakarta</artifactId>
                    <version>10.0.0.Final</version>
                    <scope>test</scope>
                </dependency>
            </dependencies>

Maven Surefire Pluginでは使用するArquillianの設定と、テスト用にプロビジョニングしたWildFlyディレクトリを指定しています。

                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <version>3.5.1</version>
                        <configuration>
                            <systemPropertyVariables>
                                <arquillian.launch>wildfly-managed</arquillian.launch>
                                <provisioned.wildfly.home>${project.build.directory}/wildfly-arquillian-managed</provisioned.wildfly.home>
                            </systemPropertyVariables>
                        </configuration>
                    </plugin>

対応するArquillianの設定はこちら。

    <container qualifier="wildfly-managed">
        <configuration>
            <property name="jbossHome">${provisioned.wildfly.home}</property>
        </configuration>
    </container>

WildFly Maven Pluginの設定。

                    <plugin>
                        <groupId>org.wildfly.plugins</groupId>
                        <artifactId>wildfly-maven-plugin</artifactId>
                        <version>5.0.1.Final</version>
                        <executions>
                            <execution>
                                <id>package</id>
                                <goals>
                                    <goal>package</goal>
                                </goals>
                                <configuration>
                                    <overwrite-provisioned-server>true</overwrite-provisioned-server>
                                    <discover-provisioning-info>
                                        <version>33.0.2.Final</version>
                                    </discover-provisioning-info>
                                </configuration>
                            </execution>
                            <execution>
                                <id>test-provisioning</id>
                                <goals>
                                    <goal>provision</goal>
                                </goals>
                                <phase>process-test-classes</phase>
                                <configuration>
                                    <provisioning-dir>${project.build.directory}/wildfly-arquillian-managed</provisioning-dir>
                                    <provisioning-file>${project.build.directory}/glow-scan/provisioning.xml</provisioning-file>
                                    <skip>${skipTests}</skip>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>

Bootable JARの時と違うのは指定するゴールがprovisionになっていることですね。Bootable JARは作らないので。

                            <execution>
                                <id>test-provisioning</id>
                                <goals>
                                    <goal>provision</goal>
                                </goals>
                                <phase>process-test-classes</phase>
                                <configuration>
                                    <provisioning-dir>${project.build.directory}/wildfly-arquillian-managed</provisioning-dir>
                                    <provisioning-file>${project.build.directory}/glow-scan/provisioning.xml</provisioning-file>
                                    <skip>${skipTests}</skip>
                                </configuration>
                            </execution>

provisionゴールでは、プロジェクトのアーティファクトのデプロイは行われません。

provisioning-dirは、Maven Surefire Pluginで指定しているシステムプロパティの値と合わせておきます。

WildFly Glow Arquillian Maven Pluginの設定は、Bootable JARの時と同じです。WildFly Maven Pluginは、WildFly Glow Arquillian Maven Pluginの
検出結果を使ってプロビジョニングを行います。

確認。

$ mvn -P managed test

WARファイルを含めてプロビジョニングする場合。

$ mvn -P managed package

## テストをスキップする場合
$ mvn -P managed package -DskipTests=true

こちらの設定でも、-DskipTests=trueを指定した時にWildFly Glow Arquillian Maven PluginおよびWildFly Maven Pluginのテスト用の
プロビジョニングはスキップするように設定しています。

プロビジョニングされたサーバーを実行する場合はこちら。

$ target/server/bin/standalone.sh
Remote

最後はRemoteです。WildFly Glow Arquillian Maven Pluginは使わないので少し主旨から外れるのですが。

WildFly Maven Pluginを使ってプロビジョニングして、起動したWildFlyに対してArquillianでテストを実行してみることにします。

設定はこちら。

        <profile>
            <id>remote</id>

            <dependencies>
                <dependency>
                    <groupId>org.wildfly.arquillian</groupId>
                    <artifactId>wildfly-arquillian-container-remote</artifactId>
                    <scope>test</scope>
                    <exclusions>
                        <exclusion>
                            <!-- arquillian-protocol-servlet-jakarta 1.9.1.Finalはない… -->
                            <groupId>org.jboss.arquillian.protocol</groupId>
                            <artifactId>arquillian-protocol-servlet-jakarta</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
                <dependency>
                    <groupId>org.jboss.arquillian.protocol</groupId>
                    <artifactId>arquillian-protocol-servlet-jakarta</artifactId>
                    <version>10.0.0.Final</version>
                    <scope>test</scope>
                </dependency>
            </dependencies>

            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <version>3.5.1</version>
                        <configuration>
                            <systemPropertyVariables>
                                <arquillian.launch>wildfly-remote</arquillian.launch>
                            </systemPropertyVariables>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.wildfly.plugins</groupId>
                        <artifactId>wildfly-maven-plugin</artifactId>
                        <version>5.0.1.Final</version>
                        <executions>
                            <execution>
                                <id>package</id>
                                <goals>
                                    <goal>package</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <overwrite-provisioned-server>true</overwrite-provisioned-server>
                            <discover-provisioning-info>
                                <version>33.0.2.Final</version>
                            </discover-provisioning-info>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

WildFly Arquillian Adapterはwildfly-arquillian-container-remoteを使います。

            <dependencies>
                <dependency>
                    <groupId>org.wildfly.arquillian</groupId>
                    <artifactId>wildfly-arquillian-container-remote</artifactId>
                    <scope>test</scope>
                    <exclusions>
                        <exclusion>
                            <!-- arquillian-protocol-servlet-jakarta 1.9.1.Finalはない… -->
                            <groupId>org.jboss.arquillian.protocol</groupId>
                            <artifactId>arquillian-protocol-servlet-jakarta</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
                <dependency>
                    <groupId>org.jboss.arquillian.protocol</groupId>
                    <artifactId>arquillian-protocol-servlet-jakarta</artifactId>
                    <version>10.0.0.Final</version>
                    <scope>test</scope>
                </dependency>
            </dependencies>

Maven Surefire Pluginでは、Remote用のArquillianの設定を指定。

                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <version>3.5.1</version>
                        <configuration>
                            <systemPropertyVariables>
                                <arquillian.launch>wildfly-remote</arquillian.launch>
                            </systemPropertyVariables>
                        </configuration>
                    </plugin>

対応するArquillianの設定は、中身は空にしてあります。

    <container qualifier="wildfly-remote">
    </container>

WildFly Maven Pluginの設定は、ふつうにプロビジョニングしているだけですね。

                    <plugin>
                        <groupId>org.wildfly.plugins</groupId>
                        <artifactId>wildfly-maven-plugin</artifactId>
                        <version>5.0.1.Final</version>
                        <executions>
                            <execution>
                                <id>package</id>
                                <goals>
                                    <goal>package</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <overwrite-provisioned-server>true</overwrite-provisioned-server>
                            <discover-provisioning-info>
                                <version>33.0.2.Final</version>
                            </discover-provisioning-info>
                        </configuration>
                    </plugin>

で、ここからどうやってテストするかというと、最初にWildFlyをプロビジョニングします。

$ mvn -P remote package -DskipTests=true -Dwildfly.package.deployment.skip=true

この時にwildfly.package.deployment.skiptrueにして、プロビジョニングするWildFlyにプロジェクトのアーティファクトをデプロイ
しないようにしています。

プロビジョニングが終わったら、WildFlyを起動。

$ mvn -P remote wildfly:start

このコマンドでは、WildFlyをバックグランドで起動します。

あとはテストを実行するだけです。

$ mvn -P remote test

これで、wildfly:startで起動したWildFlyに対してテスト対象をデプロイしてテストを実行します。

テストが終わったら、wildfly:shutdownWildFlyを停止します。

$ mvn -P remote wildfly:shutdown

ふつうにプロビジョニングする時は、テストはスキップすることになるでしょうね。

$ mvn -P remote package -DskipTests=true

プロビジョニングしたWildFlyの起動はこちら。

$ target/server/bin/standalone.sh

こんなところでしょうか。

おわりに

ArquillianとWildFly Glowを組み合わせる時には、WildFly Glow Arquillian Maven Pluginを使って必要なレイヤーなどを検出してテスト用に
プロビジョニングする必要があることがわかりました。また、WildFly Glow Arquillian Maven Pluginの基本的な使い方もわかったと思います。

とはいえ、WildFly Glow自体は便利だと思うのですが、テストの度に必要なレイヤーのみに絞って軽量化しているとはいえWildFly
起動しなおすのは重たいので、最後のRemoteを使った形態でいいのでは…?と思ったり。

まあ、WildFly Glowの周辺知識として覚えておきましょう。