Digital Developer Conference: Hybrid Cloud 2021. On Sep 21, gain free hybrid cloud skills from experts and partners. Register now

Run true-to-production tests on your MicroProfile and JakartaEE applications

In application development, it’s important to test your application in a true-to-production environment before releasing your application to consumers. Traditionally, developers have struggled with replicating an application’s production environment locally. New build tools such as Maven and Gradle make integrating testing technology into your current projects easier.

In this article, I introduce you to a testing tool — MicroShed Testing — that I’ve found make this true-to-production testing better. I walk you through an example using the tool to test sample code.

Why use MicroShed Testing?

The MicroShed testing implementation is based on the Testcontainers framework and allows for true-to-production integration tests on your local machine with Jakarta EE and MicroProfile. This enables you to minimize the amount of test failures due to differences in dev/test and production environments. Using the magic of containers, you can replicate what you have in your production environment without much setup at all. This testing works with many different runtimes such as Open Liberty and provides integration with applications using Apache Kafka for messaging.

Prerequisites

To follow the examples in this article, install:

  • Java
  • Maven
  • Docker

Add JUnit dependencies

You can use MicroShed testing with build tools such as Maven or Gradle. The example below shows you how to add the correct dependencies in Maven. This example uses JUnit tests, so you will also require the JUnit dependency. Add the following dependencies to the dependency list in your POM file:

<dependency>
    <groupId>org.microshed</groupId>
    <artifactId>microshed-testing-liberty</artifactId>
    <version>0.9.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.6.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>testcontainers</artifactId>
    <version>1.15.1</version>
    <scope>test</scope>
</dependency>

Create a MircroShed test

A MicroShed test is like a normal JUnit test, but it runs in a container. You need to add a few things to your testing class so that the build knows it is a MicroShed test.

  1. First, you need to add the MicroShed Test import and the @MicroShedTest annotation at the top of the class.

     import org.microshed.testing.jupiter.MicroShedTest;
     @MicroShedTest
     public class MyTest {
     …
     }
    
  2. Import the ApplicationContainer class and the container annotation to create the container where you will run your tests.

     import org.microshed.testing.jupiter.MicroShedTest;
     import org.microshed.testing.testcontainers.ApplicationContainer;
     import org.testcontainers.junit.jupiter.Container;
    
     @MicroShedTest
     public class MyTest {
     @Container
     }
    
  3. Create a new method inside your container called withAppContextRoot(String) that allows you to set the path to your application. In this case, the path is “/myservice”.

  4. Use withReadinessPath(String) that checks if the application is ready and available before it starts testing and sending requests.

     import org.microshed.testing.jupiter.MicroShedTest;
     import org.microshed.testing.testcontainers.ApplicationContainer;
     import org.testcontainers.junit.jupiter.Container;
    
     @MicroShedTest
     public class MyTest {
         @Container
         public static MicroProfileApplication app
             = new MicroProfileApplication()
                   .withAppContextRoot("/myservice")
         .withReadinessPath(“/health/ready”);
     }
    
  5. Add in your REST client to test against. To do this, use the import org.microshed.testing.jaxrs.RESTClient;. Then you simply create an instance of your REST client and annotate it with the @RESTClient annotation.

    import org.junit.jupiter.api.Test;
    import org.microshed.testing.jaxrs.RESTClient;
    import org.microshed.testing.jupiter.MicroShedTest;
    import org.microshed.testing.testcontainers.ApplicationContainer;
    import org.testcontainers.junit.jupiter.Container;

    @MicroShedTest
    public class MyTest {
        @Container
        public static MicroProfileApplication app
            = new MicroProfileApplication()
                  .withAppContextRoot("/myservice")
          .withReadinessPath(“/health/ready”);

        // Inject JAX-RS REST Client          
        @RestClient
        public static MyService mySvc;
    }
  1. Create your test methods as you would for a normal JUnit test, and test them against the newly created REST Client class you created previously.
  2. To start a test, simply run a Maven build with your testing stage enabled (enabled by default in Maven). In your terminal, you will that it will start up a container with your application inside, wait for the readiness probe to get a 200-response code, and begin running your tests inside a container.
    import org.junit.jupiter.api.Test;
    import org.microshed.testing.jaxrs.RESTClient;
    import org.microshed.testing.jupiter.MicroShedTest;
    import org.microshed.testing.testcontainers.ApplicationContainer;
    import org.testcontainers.junit.jupiter.Container;

    @MicroShedTest
    public class MyTest {

        // Search for Dockerfile.
        // Start app in Container.
        // Wait for Container before running tests.
        @Container
        public static MicroProfileApplication app
            = new MicroProfileApplication()
                  .withAppContextRoot("/myservice")
    .withReadinessPath(“/health/ready”);

        // Inject JAX-RS REST Client          
        @RestClient
        public static MyService mySvc;

        // A test method like any other
        @Test
        public void testMyService() {
            ...
        }
    }

Summary

Testing in containers with MicroShed testing can save developers time and stress by making the testing environment they use as close to production as possible. This enables us to use Docker files to easily configure local Docker containers that act as throw away testing environments.