Skip to content

Latest commit

 

History

History
160 lines (114 loc) · 7.2 KB

README.adoc

File metadata and controls

160 lines (114 loc) · 7.2 KB

JEE Testcontainers badge badge

Simply start and stop Jakarta EE containers and deploy applications for your integration tests. This is an extension to Testcontainers for Jakarta EE application servers, so Docker is used under the hood, but you don’t need to write, e.g., a Dockerfile.

Prototypical Example:

@Testcontainers
public class MyAppIT {
    @Container static JeeContainer CONTAINER = JeeContainer.create()
        .withDeployment("target/my-app.war");

    @Test void shouldGetStatusResponse() {
        String body = CONTAINER.target().request(APPLICATION_JSON_TYPE).get(String.class);

        then(body).isEqualTo("{\"status\":\"okay\"}");
    }
}

Or if you have an implementation of Microprofile Rest Client on your test classpath:

@Testcontainers
public class MyAppIT {
    @Container static JeeContainer CONTAINER = JeeContainer.create()
        .withDeployment("target/my-app.war");

    @Data public static class Status {
        String condition;
    }

    public interface StatusApi {
        @GET Status getStatus();
    }

    @Test void shouldGetStatusResponse() {
        StatusApi body = CONTAINER.restClient(StatusApi.class);

        Status status = body.getStatus();

        then(status.getCondition()).isEqualTo("okay");
    }
}

The console output of the container is piped to the test’s output, STDOUT in green and STDERR in blue.

Deployments

As seen in the prototypical example above, you can install an application by calling .withDeployment(<file>).

Instead of a local file, you can also install from an URL. Or you can use a maven URN like urn:mvn:org.jolokia:jolokia-war-unsecured:1.6.3:war.

Container Image

Set the system property jee-testcontainer to one of the keys in the following table to select the corresponding container. Ideally you shouldn’t have to care about what server your application runs on, or you may even want to test it in multiple containers. Then you can run your test suite in your CI pipeline with different system properties.

You can append a tag to the jee-testcontainer separated by a colon :. This is often simply the version of the container; e.g. wildfly:27.0.0.Final.

Key Container Docker Image Notes

wildfly

WildFly

wildfly/wildfly

default container on quay.io

open-liberty

Open Liberty

open-liberty

we add server.xml with features javaee-10.0 and microProfile-5.0

tomee

TomEE

tomee

Official image

payara

Payara

payara

not an 'official' image on Docker-Hub

Reuse

You can reuse a running container instance for all tests as long as the config doesn’t change, by calling withReuse(true). This feature is marked as unstable from testcontainers.org. You can achieve the same by setting the system property testcontainer-reuse to true, which comes in handy when you need it only for certain launch configurations, i.e. local or on CI.

Ports

By default, the main port exposed by the container (which accidentally is 8080 in all currently supported JEE servers) is published/bound to a random free port. You can bind it to a fixed port by calling JeeContainer#withMainPortBoundToFixedPort(int hostPort). Or you can set the testcontainer-with-main-port-bound-to-fixed-port system property for the same effect.

Similarly, you can publish any port by calling JeeContainer#withPortBoundToFixedPort(int hostPort, int containerPort).

Fixing port numbers may be convenient in some cases, but you shouldn’t do this without a good reason.

Modifications

You can modify the deployable in two ways. You can have multiple and repeated modification to, e.g., rename the file and add multiple libraries.

Rename

import static com.github.t1.testcontainers.jee.NamedAsMod.namedAs;

@Testcontainers
public class MyAppIT {
    @Container static JeeContainer CONTAINER = JeeContainer.create()
        .withDeployment("target/my-app.war", namedAs("foo.war"));
}

Add Library

import static com.github.t1.testcontainers.jee.AddLibMod.addLib;

@Testcontainers
public class MyAppIT {
    @Container static JeeContainer CONTAINER = JeeContainer.create()
        .withDeployment("target/my-app.war", addLib("urn:mvn:org.jolokia:jolokia-war-unsecured:1.6.3:war"));
}

Add Config

import static com.github.t1.testcontainers.jee.ConfigMod.config;

@Testcontainers
public class MyAppIT {
    @Container static JeeContainer CONTAINER = JeeContainer.create()
        .withDeployment("target/my-app.war", config("foo", "bar"));
}

Configure the MP Config key foo to be bar. Creates or appends to WEB-INF/classes/META-INF/microprofile-config.properties.

Container Configuration

You can configure the log level of a logger, e.g. by calling withLogLevel (at the moment, this only works for WildFly containers, but we’re open for PRs 😀).

You can also configure a data source by calling withDataSource(DB), where DB is a JdbcDatabaseContainer (currently only PostgreSQLContainer and only on WildFly).

For WildFly, you can also call arbitrary CLI commands by calling withCli.

Apart from that, you can’t currently configure anything else for your application, e.g. add message queues. I will add such things whenever I need it, but again: PRs are welcome.

Building A Test Deployable

There’s a very limited support to build a war deployable from scratch. See the API of the DeployableBuilder class for details. If you need more, maybe ShrinkWrap can help, but I haven’t tried that in combination, yet.