Arquillian Testcontainers is a loadable extension for Testcontainers support. This project is not meant to provide an Arquillian adaptor via a Testcontainer, but rather compliment an Arquillian adaptor by allowing Arquillian to manage a Testcontainer.
To start using Arquillian Testcontainers add the following Maven dependency:
<dependency>
<groupId>org.arquillian.testcontainers</groupId>
<artifactId>arquillian-testcontainers</artifactId>
<version>${version.org.arquillian.testcontainers}</version>
<scope>test</scope>
</dependency>To use a Testcontainer within an Arquillian test you must annotate the type with @TestcontainersRequired. What this annotation
does is verify a Docker implementation is available. If a Docker implementation is not available, an exception is thrown.
By default, this is a java.lang.AssertionError. This can be overridden in the @TestcontainersRequired(value=) attribute. For
example in JUnit 5 to skip the test rather than throw an error you would use the @TestcontainersRequired(TestAbortedException.class).
This would throw a org.opentest4j.TestAbortedException if a Docker implementation is not available and the test will
be skipped.
To inject a Testcontainer into your Arquillian test, use the @Testcontainer annotation.
@ExtendWith(ArquillianExtension.class)
@TestcontainersRequired(TestAbortedException.class)
@RunAsClient
public class SimpleContainerTest {
@Testcontainer
private static SimpleTestContainer container;
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Test
public void testContainerInjected() {
Assertions.assertNotNull(container, "Expected the container to be injected.");
Assertions.assertTrue(container.isRunning(), "Expected the container to not be running");
}
}The injected type must be an implementation of org.testcontainers.containers.GenericContainer. If you would like to
inject a GenericContainer<?>, you can use the type parameter in the @Testcontainer annotation to qualify the type:
@ExtendWith(ArquillianExtension.class)
@RunAsClient
@TestcontainersRequired(TestAbortedException.class)
public class TypeSpecifiedInjectionTest {
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Testcontainer(type = WildFlyContainer.class)
private GenericContainer<?> wildfly;
@Testcontainer(type = SimpleTestContainer.class)
private GenericContainer<?> container;
@Test
public void checkWildFly() {
Assertions.assertNotNull(wildfly);
Assertions.assertTrue(wildfly.isRunning());
}
@Test
public void checkSimpleTestContainer() {
Assertions.assertNotNull(container, "Expected the container to be injected.");
Assertions.assertTrue(container.isRunning(), "Expected the container to be running");
}
}By default, this extension will manage the lifecycle of each Testcontainer that is injected into the test. If you’d
prefer to manage the lifecycle yourself, use the value=true attribute in the @Testcontainer annotation. For example
use @Testcontainer(false).
Arquillian Testcontainers contains a helper for consuming log messages. The LoggingConsumer simply consumes the
containers output and logs it via a java.util.logging.Logger.
The following is an example of using a Testcontainer in WildFly with a ServerSetupTask.
@TestcontainersRequired
@ExtendWith(ArquillianExtension.class)
@RunAsClient
@ServerSetup(WildFlyTest.ContainerSetupTask.class)
public class WildFlyTest {
@TestcontainersRequired
@ReloadIfRequired
public static class ContainerSetupTask implements ServerSetupTask {
@Testcontainer
private KeycloakContainer keycloak;
@Override
public final void setup(final ManagementClient managementClient, final String containerId) throws Exception {
final var containerAddress = keycloak.getContainerAddress();
// Do the Keycloak setup
}
@Override
public final void tearDown(final ManagementClient managementClient, final String containerId) throws Exception {
}
}
@Testcontainer
private KeycloakContainer keycloak;
@Deployment
public static WebArchive createDeployment() {
return ShrinkWrap.create(WebArchive.class)
.addClasses(SecureEndpoint.class, SecureApplication.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Test
public void auth() throws Exception {
final var response = makeRequest(keycloak.getContainerAddress(keycloak.getMappedPort(8080)));
// Validate response
}
}Releasing the project requires permission to deploy to Maven Central see Maven Central Release Requirements.
Once everything is setup, you simply need to run the ./release.sh script. There are two required parameters:
-
-ror--releasewhich is the version you want to release -
-dor--developmentwhich is the next development version.
By default, the release version cannot contain SNAPSHOT and the development version, must container SNAPSHOT.
./release -r 1.0.0.Final -d 1.0.1.Final-SNAPSHOT| Argument | Requires Value | Description |
|---|---|---|
|
Yes |
The next version for the development cycle. |
|
No |
Forces to allow a SNAPSHOT suffix in release version and not require one for the development version. |
|
No |
Displays help |
|
No |
Indicates this is a prerelease and the GitHub release should be marked as such. |
|
Yes |
The version to be released. Also used for the tag. |
|
No |
Executes the release in as a dry-run. Nothing will be updated or pushed. |
|
No |
Prints verbose output. |
Any additional arguments are considered arguments for the Maven command.