How to Test your Applications in Payara Server

Photo of Luis Neto by Luis Neto

Why is software testing so important? Firstly, because we are all susceptible to making mistakes.
Secondly, because the sooner we find bugs and fix them, the cheaper the fix!

We should write tests to: identify defects, reduce flaws in the application and increase the overall quality of the software. The purpose of this blog is not to teach application testing in detail, but we will cover the basics of how to run tests on Payara Server using JUnit, TestNG and Arquillian. You can find a detailed, free Jakarta EE testing guide here

Arquillian is a testing framework for Jakarta EE. Using Arquillian reduces the time spent managing containers, deployments and framework initializations. This means you can focus on writing actual tests and not on bootstrapping the test environment. For more information about Arquillian clickhere. 

Configuration

Arquillian is easy to integrate into your projects with Maven. In your Maven POM, include the following dependencies, excluding the JUnit or TestNG dependency as per your preference or requirements:

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

<dependencies>

<!-- Junit -->
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
...

<!-- TestNG -->
<dependency>
<groupId>org.jboss.arquillian.testng</groupId>
<artifactId>arquillian-testng-container</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.6.1</version>
<scope>test</scope>
</dependency>
...
</dependencies>

The last thing to configure is the container, namely Payara Server or Micro. Five options are presented here:

  • Payara Embedded - Starting Payara Server for testing can be done more easily in the embedded form because it manages the lifecycle of an embedded container (runs in the same JVM as the test runner). You can read more about our Arquillian connector for Payara Embedded on thedocumentation page.
  • Server Managed - Manages the lifecycle of a local installation of the container/server. This means that the full application server is used to run the tests, so this might impact the footprint of the suite, including the time to start/stop the container. Typically used if you want to test against a Full Payara Server instance but want everything to be managed by Maven (so you don’t have to set up an instance separately). Given that the container is managed by Maven, you can’t just drop in the dependency and be good to go; you need to configure how Maven will find and use a Payara Server installation.
  • Micro Managed - Similar to Server Managed, except uses a Payara Micro instance instead of a Payara Server one. Just as with the Server Managed container, this isn’t a simple drop-in and play container, requiring you to perform some additional configuration.
  • Payara Remote - The adapter itself doesn't manage the lifecycle of a container but binds to an already running container, either locally or on a remote location. This can simplify tests in many scenarios when the continuous integration workflow depends on an already configured application server's instance since the tests only need to know where the server is located and Arquillian manages the communication to it.
  • Micro Remote - Similar to Payara Remote, except binds an already running Payara Micro instance instead of a Payara Server one.
Payara Embedded
<dependency>
<groupId>fish.payara.arquillian</groupId>
<artifactId>arquillian-payara-server-embedded</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>fish.payara.extras</groupId>
<artifactId>payara-embedded-all</artifactId>
<version>5.2022.3</version><<
<scope>test</scope>
</dependency>
Server Managed
<dependency>
<groupId>fish.payara.arquillian</groupId>
<artifactId>arquillian-payara-server-managed</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>
Micro Managed
<dependency>
<groupId>fish.payara.arquillian</groupId>
<artifactId>arquillian-payara-micro-managed</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>
Payara Remote
<dependency>
<groupId>fish.payara.arquillian</groupId>
<artifactId>arquillian-payara-server-remote</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>
Micro Remote
<dependency>
<groupId>fish.payara.arquillian</groupId>
<artifactId>payara-micro-remote</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>

Running The Tests Against Payara Server

To run tests with Arquillian against Payara Server, test classes must be annotated with @RunWith (Arquillian.class) for JUnit tests or extend the Arquillian class:
public class ATest extends Arquillian for TestNG tests, and have a method annotated with @Deployment to create and deploy a test archive.

Arquillian uses test archives to specify the classes and resources required for the test to deploy and run. These test archives use the ShrinkWrap class which provides an API to create deployable *.jar, *.war, and *.ear files, allowing the tests to range from basic unit tests, to complicated integration and functional tests.

Then you just need to annotate your test methods with @Test or @Test() for JUnit or TestNG respectively, and run them!

An Example

To help put things into context, we will demonstrate a very basic test using TestNG, Maven, and Payara Micro (we are assuming you already know how to create a Maven project with a src & test folder structure, otherwise check out First Maven Project Documentation). First, fill out the POM file with the required dependencies we described before so it looks like this:

<?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>fish.payara.examples</groupId>
<artifactId>arquillian-example</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Arquillian Example</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<payara.version>5.2022.3</payara.version>
</properties>

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

<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0.1</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.jboss.arquillian.testng</groupId>
<artifactId>arquillian-testng-container</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.6.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>fish.payara.arquillian</groupId>
<artifactId>arquillian-payara-micro-managed</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<!-- Download and copy Payara Micro artefact -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>process-test-classes</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<skip>${skipTests}</skip>

<artifactItems>
<artifactItem>
<groupId>fish.payara.extras</groupId>
<artifactId>payara-micro</artifactId>
<version>${payara.version}</version>
<overWrite>false</overWrite>
<outputDirectory>${session.executionRootDirectory}/target/</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>

<!-- Configure Payara Micro Runtime -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<environmentVariables>
<MICRO_JAR>${session.executionRootDirectory}/target/payara-micro-${payara.version}.jar</MICRO_JAR>
</environmentVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>

As a managed container, we need to configure how Maven will find and use a Payara Micro instance. In this example, we use the Maven Dependency plugin to download the Payara Micro artefact, and then copy it into the target directory. We then use the Maven Surefire plugin (this is Maven’s test plugin) to set the MICRO_JAR environment variable, pointing it to the downloaded artefact. This environment variable is then used by the Arquillian container to locate the Payara Micro JAR that should be used.

Now we need an application to test. The following is a Hello World application with just a single method:

package fish.payara.examples.arquillian;

public class HelloWorld {

public String sayHello() {
return "Hello World";
}

}

Then, you need a test class. This test class simply creates the deployment for Arquillian, and checks that the message being returned by the sayHello() method is correct:

package fish.payara.examples.arquillian;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.testng.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.testng.Assert;
import org.testng.annotations.Test;

public class HelloWorldTest extends Arquillian {

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

@Test()
public void sayHelloTest() {
HelloWorld helloWorld = new HelloWorld();
Assert.assertEquals(helloWorld.sayHello(), "Hello World");
}
}

Finally, we can run the test with one command: mvn clean test

This command compiles the application, starts a Payara Micro instance, deploys the test application, and run tests against it.

What's Next?

Hopefully this should give you enough of a start to begin running your own tests against Payara Server. If you still need some extra help though, the Arquillian website hosts someArquillian guides. Alternatively, you can check out theJava EE 8 Sample repository, which also make use of Payara Server & Micro with Arquillian.

Comments