Testing with the Arquillian Managed container

Note
This repository contains the guide documentation source. To view the guide in published form, view it on the Open Liberty website.

Learn how to run integration tests for your Open Liberty application using the Arquillian Liberty Managed container.

What you’ll learn

You will learn how to run integration tests for your Open Liberty application using the Arquillian Liberty Managed container and JUnit with Maven or Gradle. For either of these build tools, you will also learn how to take advantage of features in the Liberty plugin that will simplify the process of managing Arquillian dependencies and setting up your Liberty Managed container.

Try what you’ll build

To try running the finished Arquillian test, navigate to the finish folder and execute the Maven or Gradle build:

cd finish
mvn install # If you're using Maven
gradle build # If you're using Gradle

Between the server start and stop messages, you will see the following console output indicating that your test has passed.

PhraseBuilder <init>
PhraseBuilder <init>
PhraseBuilder initialize
Hello, Earthling!

This will be followed shortly by a message indicating a successful build.

Configuring your test build

Using Maven

To configure your build to run your Arquillian tests using Maven, modify the start/pom.xml file to add your Arquillian and Liberty dependencies. For instructions on doing this with Gradle, skip to the "Using Gradle" section below.

All of the Maven configuration will take place in the pom.xml file. Start by adding the Liberty Maven App Parent POM. This will configure the Liberty Maven Plugin with the default executions necessary for setting up your managed Liberty server.

<parent>
	<groupId>net.wasdev.wlp.maven.parent</groupId>
	<artifactId>liberty-maven-app-parent</artifactId>
	<version>2.4.2</version>
</parent>

Next, add the Arquillian Bill of Materials (BOM). A BOM is a Maven artifact which defines versions of dependencies to make dependency management easier.

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.jboss.arquillian</groupId>
			<artifactId>arquillian-bom</artifactId>
			<version>1.4.0.Final</version>
			<scope>import</scope>
			<type>pom</type>
		</dependency>
	</dependencies>
</dependencyManagement>

Next, add the Arquillian Liberty Managed JUnit dependency bundle and the Arquillian Shrinkwrap API. The dependency bundle includes all the core dependencies for running Arquillian tests on a managed Liberty container using JUnit. You can learn more about the Arquillian Liberty dependency bundles here. Adding the Shrinkwrap API will allow you to create your test archive which will be packaged into a WAR and deployed to the Open Liberty server.

<dependency>
	<groupId>io.openliberty.arquillian</groupId>
	<artifactId>arquillian-liberty-managed-junit</artifactId>
	<version>1.1</version>
	<type>pom</type>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>org.jboss.shrinkwrap</groupId>
	<artifactId>shrinkwrap-api</artifactId>
	<scope>test</scope>
</dependency>

Finally, add the Maven Failsafe Plugin and the Liberty Maven Plugin. The Failsafe plugin is used to run your JUnit integration tests, while the Liberty Maven Plugin configuration specifies your Open Liberty runtime and uses the configure-arquillian goal to automatically create and configure your arquillian.xml. This goal will retrieve the core wlpHome, serverName, and httpPort parameter values automatically from the Liberty Maven Plugin configuration, and also allows you to specify additional arquillian.xml parameters directly in your POM in an arquillianProperties dictionary. Complete documentation for this goal can be found here. Also notice in the configuration that skipTestServer is set to true to skip the test-start-server and test-stop-server goals defined in the Liberty Maven App Parent. This is because Arquillian will be managing the server lifecycle when it runs the tests.

<build>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-failsafe-plugin</artifactId>
			<version>2.21.0</version>
			<executions>
				<execution>
					<id>failsafe-integration-test</id>
					<phase>integration-test</phase>
					<goals>
						<goal>integration-test</goal>
					</goals>
				</execution>
				<execution>
					<id>failsafe-verify</id>
					<phase>verify</phase>
					<goals>
						<goal>verify</goal>
					</goals>
				</execution>
			</executions>
		</plugin>

		<plugin>
			<groupId>net.wasdev.wlp.maven.plugins</groupId>
			<artifactId>liberty-maven-plugin</artifactId>
			<version>2.4.2</version>
			<extensions>true</extensions>
			<!-- Specify configuration, executions for liberty-maven-plugin -->
			<configuration>
				<serverName>ArquillianManagedServer</serverName>
				<assemblyArtifact>
					<groupId>io.openliberty</groupId>
					<artifactId>openliberty-runtime</artifactId>
					<version>[17.0.0.4,)</version>
					<type>zip</type>
				</assemblyArtifact>
				<features>
					<acceptLicense>true</acceptLicense>
				</features>
				<skipTestServer>true</skipTestServer>
			</configuration>
			<executions>
				<execution>
					<id>install-apps</id>
					<phase>none</phase>
				</execution>
				<execution>
					<id>configure-arquillian-xml</id>
					<phase>pre-integration-test</phase>
					<goals>
						<goal>configure-arquillian</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

Using Gradle

To configure your build to run your Arquillian tests using Gradle, modify the start/build.gradle file to add your Arquillian and Liberty dependencies. For instructions on doing this with Maven, scroll up to the "Using Maven" section above.

All of the Gradle configuration will take place in the build.gradle file. Start by adding the Liberty Gradle Plugin and Gradle dependency management plugin as part of the buildscript dependencies. The Liberty Gradle Plugin allows you to manage your Liberty server, while the dependency management plugin brings support for Maven BOMs (Bill of Materials) to Gradle. You can learn more about the dependency management plugin here.

dependencies {
    classpath group: 'net.wasdev.wlp.gradle.plugins', name: 'liberty-gradle-plugin', version: '2.4.1'
    classpath "io.spring.gradle:dependency-management-plugin:1.0.4.RELEASE"
}

Next, apply the two plugins that you just added:

apply plugin: 'liberty'
apply plugin: "io.spring.dependency-management"

Now add the Liberty server configuration. All that’s needed is to point the plugin to the location of your server.xml. You can also optionally assign a server name as shown below.

liberty {
    server {
        configFile = file("${rootProject.projectDir}/src/test/resources/server.xml")
        name = 'ArquillianManagedServer'
     }
}

Next, add the Arquillian Bill of Materials (BOM). A BOM is a Maven artifact which defines versions of dependencies to make dependency management easier.

dependencyManagement {
    imports {
        mavenBom "org.jboss.arquillian:arquillian-bom:1.4.0.Final"
    }
}

Then, add your test dependencies and the Open Liberty runtime to the dependencies section. The Arquillian Liberty Managed JUnit dependency bundle includes all the core dependencies for running Arquillian tests on a managed Liberty container using JUnit. You can learn more about the Arquillian Liberty dependency bundles here. Adding the Shrinkwrap API will allow you to create your test archive which will be packaged into a WAR and deployed to the Open Liberty server. You will also need to point to the tools.jar file provided by the JDK.

testCompile group: "io.openliberty.arquillian", name: "arquillian-liberty-managed-junit", version: "1.1"
testCompile ('org.jboss.shrinkwrap:shrinkwrap-api')
testCompile files("${System.properties['java.home']}/../lib/tools.jar")

libertyRuntime "io.openliberty:openliberty-runtime:18.0.0.1"

Finally, add your test configuration. Notice that the tests depend on the configureArquillian task. This task will automatically create and configure your arquillian.xml by retrieving the core wlpHome, serverName, and httpPort parameter values from the Liberty Gradle Plugin configuration. It also allows you to specify additional arquillian.xml parameters directly in your build.gradle file in an arquillianConfiguration dictionary. Complete documentation for this goal can be found here.

tasks.withType(Test) {
    group 'Verification'
    testLogging.showStandardStreams = true
    reports.html.destination = file("$buildDir/reports/")
    reports.junitXml.destination = file("$buildDir/test-results/")
    include '**/*'
    dependsOn 'installApps', 'testClasses', 'configureArquillian'
}

Configuring the server.xml

Now that you’re done configuring the build tool of your choice, edit the src/test/resources/server.xml file:

link:finish/src/test/resources/server.xml[role=include]

Add the localConnector-1.0 feature to the featureManager block. This is a feature that is required by the Arquillian Liberty Managed container in order to connect to and communicate with the Open Liberty runtime.

Adding your Arquillian test

You’re now ready to write your test. Notice that the source of the starting project includes two classes, Greeter and PhraseBuilder. The Greeter class injects an instance of the PhraseBuilder class, and invokes a method on it to create a greeting. Your test class will use Arquillian and JUnit to test this functionality.

Create the test file at src/test/java/org/arquillian/example/GreeterIT.java:

link:finish/src/test/java/org/arquillian/example/GreeterIT.java[role=include]

The first thing you should notice is that the JUnit Arquillian runner is being used to run the tests, instead of the standard JUnit runner. This is specified using the RunWith annotation at the top of the class, and tells JUnit to run the tests using Arquillian.

The next important item is the @Deployment block. The ShrinkWrap test archive’s contents are defined here, which is going to be deployed to Open Liberty to run the in-container tests. Notice the inclusion of the Greeter and PhraseBuilder classes. Without these, the code will compile successfully but fail at runtime when the injection of the Greeter class takes place.

CDI is used to inject an instance of the Greeter class. It is then tested by the should_create_greeting method, which validates that it creates the correct greeting based on the input.

Running the tests

This concludes the code changes. It’s now time to build and run your project. Run the command below that corresponds to your build tool of choice.

For Maven:

mvn clean install

For Gradle:

gradle clean build

In either case, you will notice that the server is created and started, with a test application built from your ShrinkWrap archive that is deployed at http://localhost:9080/test/. You will then see the initialization and execution of the test:

PhraseBuilder <init>
PhraseBuilder <init>
PhraseBuilder initialize
Hello, Earthling!

Following the execution of the test, the test application is automatically undeployed and the server is shut down. You should then get a message indicating that the build was successful.

Great work! You’re done!