Skip to content
This repository has been archived by the owner on Jun 10, 2024. It is now read-only.

1000kit/tkit-quarkus-test

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

64 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tkit-quarkus-test

Quarkus versions:

  • Tested with Quarkus 1.3.0.Final.
  • For Quarkus 1.2.1.Final or older use 0.x version

tkit quarkus test extension

License Maven Central GitHub Actions Status

Add this maven test dependency to the project.

<dependency>
    <groupId>org.tkit.quarkus</groupId>
    <artifactId>tkit-quarkus-test</artifactId>
    <version>1.7.0</version>
    <scope>test</scope>
</dependency>

DB Import

If you are testing backend service you will probably want to have some test data ready. You can quickly enable import of test data from Excel by adding dbimport feature to your test containers and annotating your test class or test method with @WithDBData. The annotation specifies a path to XLS file that should be imported and optionally whether you want to delete existing data before import. See javadoc for more info. If you have @WithDBData on class, its data will be imported before first test execution.

The data needs to be valid Excel file with DBunit structure(table per sheet). How it works: If you enable dbimport feature, the DeploymentBuilder will inject DBunit and it's dependencies into your war file along with a simple rest service that handle the file upload and import(rs path dbimport). In a @Before hook of your test method, tkit checks if a @WithDBData annotation is present and will try to upload the given file to the dbimport rest service.

Add the dbimport docker image to the test containers docker-compose.yml/docker-compose.yaml (both extensions are supported) file

  tkit-parameter-db-import:
    container_name: tkit-parameter-db-import
    image: quay.io/tkit/dbimport:master
    environment:
      DB_URL: "jdbc:postgresql://tkit-parameter-db:5432/parameters?sslmode=disable"
      DB_USERNAME: "parameters"
      DB_PASSWORD: "parameters"
    ports:
      - "8811:8080"
    labels:
      - "test.Wait.forLogMessage.regex=.*Installed features:.*"
      - "test.Wait.forLogMessage.times=1"
      - "test.log=true"
      - "test.property.tkit.test.dbimport.url=$${url:tkit-parameter-db-import:8080}"

Put the annotation to the test method

@Test
@WithDBData({"parameters-testdata.xls"})
public void testImportData() {
    given()
            .when()
            .contentType(MediaType.APPLICATION_JSON)
            .queryParam("applicationId", "app1")
            .queryParam("parameterKey", "param")
            .get("/v2/parameters")
            .prettyPeek()
            .then()
            .statusCode(Response.Status.OK.getStatusCode());
}

Build and tests

  1. Build project, run the unit test and build:
    • mvn clean package (1)
  2. Build the docker image
    • docker build
  3. Run the integration test
    • mvn failsafe:integration-test failsafe:verify
  4. Push the docker image
    • docker push

(1) build native image with a docker image or with install GraalVM

  • mvn clean package -Pnative -Dquarkus.native.container-build=true
  • mvn clean package -Pnative

How to write the tests

Create abstract test class which will set up the docker test environment. The default location of the docker compose file is src/test/resources/docker-compose.yml. For example:

version: "2"
services:
  postgres:
    container_name: postgres
    image: postgres:10.5
    environment:
      POSTGRES_DB: "parameters"
      POSTGRES_USER: "parameters"
      POSTGRES_PASSWORD: "parameters"
    labels:
      - "test.Wait.forLogMessage.regex=.*database system is ready to accept connections.*\\s"
      - "test.Wait.forLogMessage.times=2"
      - "test.log=true"
      - "test.property.quarkus.datasource.url=jdbc:postgresql://$${host:postgres}:$${port:postgres:5432}/parameters?sslmode=disable"
    ports:
      - "5433:5433"
    networks:
      - test
  tkit-parameter:
    container_name: tkit-parameter
    image: quay.io/tkit/tkit-parameter:latest
    ports:
      - "8080:8080"
    labels:
      - "test.unit=false"
      - "test.priority=101"
      - "test.image.pull=false"
      - "test.property.quarkus.http.test-port=$${port:tkit-parameter:8080}"
      - "test.env.QUARKUS_DATASOURCE_URL=jdbc:postgresql://postgres:5432/parameters?sslmode=disable"
    networks:
      - test
networks:
  test:

For integration test we set up quarkus.http.test-port=$${port:tkit-parameter:8080} the Quarkus test port.

Java code

We need to add these annotations to the AbstractTest class:

  • @QuarkusTestResource(DockerComposeTestResource.class) this annotation will star the docker test environment for unit tests.
  • @QuarkusTestcontainers this annotation will start the docker test environment for integration test @NativeImageTest.
@QuarkusTestcontainers
@QuarkusTestResource(DockerComposeTestResource.class)
public abstract class AbstractTest {

    @DockerService("tkit-parameter")
    protected DockerComposeService service;

    @BeforeEach
    public void before() {
        if (service != null) {
            RestAssured.port = service.getPort(8080);
            RestAssured.baseURI = "http://" + service.getHost();
        }
    }

}

Unit test

@QuarkusTest
public class ParameterRestControllerTest extends AbstractTest {
    
    @Test public void unitTest() { }

}

Integration test

@NativeImageTest
public class ParameterRestControllerTestIT extends ParameterRestControllerTest {
    
    @Test public void integrationTest() { }

}

Maven setup

Unit and integration test maven plugin

    <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <configuration>
            <systemProperties>
                <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
            </systemProperties>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>${surefire-plugin.version}</version>              
    </plugin>

Docker labels

label values default description
test.integration=true boolean true enable the docker for the integration test
test.unit=true boolean true enable the docker for the unit test
test.image.pull=DEFAULT string DEFAULT,ALWAYS,MAX_AGE pull docker image before test
test.image.pull.max_age string PT10 only for the MAX_AGE pull docker image before test if older than duration. Default: 10s
test.Wait.forLogMessage.regex= string null regex of the WaitStrategy for log messages
test.Wait.forLogMessage.times=1 int 1 the number of times the pattern is expected in the WaitStrategy
test.Log=true boolean true enabled log of the docker container
test.priority=100 int 100 start priority
test.property.{name}={value} string null set the system property with {name} and in the tests
test.env.{name}={value} string null set the environment variable with {name} and in the docker container
test.unit.property.{name}={value} string null set the system property with {name} and in the unit tests only
test.unit.env.{name}={value} string null set the environment variable with {name} and in the docker container for the unit tests only
test.integration.property.{name}={value} string null set the system property with {name} and in the integration tests only
test.integration.env.{name}={value} string null set the environment variable with {name} and in the docker container for the integration tests only
test.ports.fixed=true boolean false start container with fixed ports for the test

The value of the test.property.* or test.env.* supported this syntax:

  • simple value: 123 result: 123
  • host of the service: $${host:<service>} the host of the service <service>
  • port of the service: $${port:<service>:<port>} the port number of the <port> of the <service> service
  • url of the service: $${url:<service>:<port>} the url of the service http://<service>:<port>
  • system property: $${prop:<name>}
  • environment variable: ${env:<name>}

Example:

test.property.quarkus.datasource.url=jdbc:postgresql://$${host:postgres}:$${port:postgres:5432}/p6?sslmode=disable

The system property quarkus.datasource.url will be set to jdbc:postgresql://localhost:125432/p6?sslmode=disable if the docker image host of the postgres is localhost and tet containers dynamic port ot the container port 5432 is set to 125432 value.

Deprecated <=1.3.0

@QuarkusTestResource(DockerComposeTestResource.class)
public abstract class AbstractTest {

    @DockerService("quarkus-test")
    protected DockerComposeService app;

    @BeforeEach
    public void init() {
        if (app != null) {
            RestAssured.port = app.getPort(8080);
        }
    }
}

Create a common test for unit and integration test

public class ServiceRestControllerT extends AbstractTest {

    @Test
    public void serviceTest() {
        // ...        
    }
}

Unit test

@QuarkusTest
public class ServiceRestControllerTest extends ServiceRestControllerT {

}

Integration test

@DockerComposeTest
public class DeploymentRestControllerTestIT extends DeploymentRestControllerT {

}

Maven settings

Unit test maven plugin

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire-plugin.version}</version>
    <configuration>
        <systemProperties>
            <com.arjuna.ats.arjuna.objectstore.objectStoreDir>${project.build.directory}/jta</com.arjuna.ats.arjuna.objectstore.objectStoreDir>
            <ObjectStoreEnvironmentBean.objectStoreDir>${project.build.directory}/jta</ObjectStoreEnvironmentBean.objectStoreDir>
            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
        </systemProperties>
    </configuration>
</plugin>

Integration test maven plugin

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>${surefire-plugin.version}</version>
    <executions>
        <execution>
            <id>native</id>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
            <phase>integration-test</phase>
        </execution>
    </executions>
    <configuration>
        <systemPropertyVariables>
            <test.integration>true</test.integration>
        </systemPropertyVariables>
    </configuration>                
</plugin>

The system property <test.integration>true</test.integration> activate the integration test.

Create a release

mvn semver-release:release-create

Create a patch branch

mvn semver-release:patch-create -DpatchVersion=x.x.0