1. Abstract

The WildFly JUnit API module (wildfly-junit-api) provides annotations and conditions for conditional test execution. This module can be used with the WildFly JUnit Extension, Arquillian, or any other JUnit based testing framework.

2. Overview

This module provides three main annotations:

  • @RequiresModule - Conditionally run tests based on WildFly module availability

  • @AnyOf - Run tests if any of multiple module requirements are met

  • @JBossHome - Inject WildFly installation directory into test parameters

These annotations enable flexible, environment-aware testing without hardcoding assumptions about the WildFly configuration.

3. Getting Started

3.1. Maven Dependency

Add the API module to your test dependencies:

<dependency>
    <groupId>org.wildfly.testing</groupId>
    <artifactId>wildfly-junit-api</artifactId>
    <version>${version.org.wildfly.testing}</version>
    <scope>test</scope>
</dependency>

3.2. Requirements

  • Java 17 or later

  • JUnit 6.0 or later

  • WildFly installation (for module checking)

4. @RequiresModule

The @RequiresModule annotation disables tests when a required WildFly module is not available.

4.1. How It Works

The annotation checks for module existence by looking in the WildFly modules directory ($JBOSS_HOME/modules). It searches for the module’s module.xml file at the path corresponding to the module name. For example, org.jboss.as.ejb3 maps to $JBOSS_HOME/modules/org/jboss/as/ejb3/main/module.xml.

If the module is not found, the test is disabled (skipped), not failed. This is useful for:

  • Testing optional features that may not be present in all WildFly distributions

  • Running the same test suite against different WildFly configurations

  • Conditional testing based on available subsystems

4.2. Basic Usage

@RequiresModule("org.jboss.as.ejb3")
public class Ejb3Test {
    @Test
    public void testEjb() {
        // This test only runs if the EJB3 subsystem is present
    }
}

4.3. Version Requirements

You can specify a minimum module version:

@RequiresModule(
    value = "org.jboss.as.ejb3",
    minVersion = "32.0.0.Beta1",
    reason = "This test requires EJB 4.0 support",
    issueRef = "https://issues.redhat.com/browse/WFLY-12345"
)
public class Ejb4Test {
    @Test
    public void testEjb4Feature() {
        // Test implementation
    }
}

4.4. Multiple Requirements

Use multiple @RequiresModule annotations when all conditions must be met:

@RequiresModule("org.jboss.as.ejb3")
@RequiresModule("org.jboss.as.jpa")
public class EjbJpaTest {
    // Runs only if both EJB and JPA modules are available
}

5. @AnyOf

The @AnyOf annotation allows a test to run if at least one of multiple module requirements is met:

@AnyOf({
    @RequiresModule("org.jboss.resteasy.resteasy-client"),
    @RequiresModule("org.jboss.resteasy.resteasy-vertx-client")
})
public class RestClientTest {
    @Test
    public void testRestClient() {
        // Runs if either RESTEasy client module is available
    }
}

6. @JBossHome

The @JBossHome annotation injects the WildFly installation directory into test parameters:

public class ConfigTest {
    @Test
    public void testConfiguration(@JBossHome Path jbossHome) {
        Path configFile = jbossHome.resolve("standalone/configuration/standalone.xml");
        Assertions.assertTrue(Files.exists(configFile));
    }
}

Supported parameter types:

  • java.lang.String

  • java.nio.file.Path

  • java.io.File

6.1. Resolution Order

The framework resolves the WildFly installation directory in this order:

  1. jboss.home system property

  2. JBOSS_HOME environment variable

  3. jboss.home.dir system property

If none are set, a ParameterResolutionException is thrown.

7. Using with Arquillian

The API module can be used with Arquillian for conditional test execution:

@ArquillianTest
@RequiresModule("org.jboss.as.ejb3")
public class ArquillianEjbTest {

    @Deployment
    public static WebArchive createDeployment() {
        return ShrinkWrap.create(WebArchive.class)
                .addClass(MyBean.class);
    }

    @BeforeAll
    static void checkConfig(@JBossHome final Path jbossHome) throws Exception {
        if (Files.notExists(jbossHome.resolve("standalone/configuration/app.properties"))) {
            final var config = Files.createFile(jbossHome.resolve("standalone/configuration/app.properties"));
            Files.writeString(config, "test.app=testing\n");
        }
    }

    @Test
    public void testEjb() {
        // Test implementation
    }
}

8. Using with WildFly JUnit Extension

The API works seamlessly with the WildFly JUnit Extension:

@WildFlyTest
@RequiresModule("org.jboss.as.ejb3")
public class WildFlyEjbTest {

    @GenerateDeployment
    public static void createDeployment(final WebArchive deployment) {
        deployment.addClass(MyBean.class);
    }

    @Test
    public void testEjb(@JBossHome Path jbossHome) {
        // Test with both WildFly extension and API features
    }
}

9. Best Practices

9.1. Module Naming

Always use the fully qualified module name:

@RequiresModule("org.jboss.as.ejb3")  // Correct
@RequiresModule("ejb3")                // Wrong - will not be found

9.2. Descriptive Reasons

When using version requirements or complex conditions, provide clear reasons:

@RequiresModule(
    value = "org.wildfly.security.elytron",
    minVersion = "2.0.0",
    reason = "Test requires Elytron 2.0+ credential store features"
)

9.3. Combining with Other Conditions

You can combine @RequiresModule with JUnit’s built-in conditions:

@RequiresModule("org.jboss.as.ejb3")
@EnabledOnOs(OS.LINUX)
@EnabledIfSystemProperty(named = "run.integration.tests", matches = "true")
public class ConditionalTest {
    // Runs only if all conditions are met
}

Appendix A: API Reference

For complete API documentation, see the JavaDoc API Documentation.