Skip to content

Commit

Permalink
Merge pull request #24064 from glefloch/fix/23528
Browse files Browse the repository at this point in the history
Introduce integration test source set for gradle based project
  • Loading branch information
glefloch authored Mar 8, 2022
2 parents f526a8e + 2f53c5f commit b718fba
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.artifacts.ProjectDependency;
import org.gradle.api.plugins.BasePlugin;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSet;
Expand Down Expand Up @@ -78,6 +79,7 @@ public class QuarkusPlugin implements Plugin<Project> {
@Deprecated
public static final String BUILD_NATIVE_TASK_NAME = "buildNative";
public static final String TEST_NATIVE_TASK_NAME = "testNative";

@Deprecated
public static final String QUARKUS_TEST_CONFIG_TASK_NAME = "quarkusTestConfig";

Expand All @@ -87,6 +89,11 @@ public class QuarkusPlugin implements Plugin<Project> {
public static final String NATIVE_TEST_IMPLEMENTATION_CONFIGURATION_NAME = "nativeTestImplementation";
public static final String NATIVE_TEST_RUNTIME_ONLY_CONFIGURATION_NAME = "nativeTestRuntimeOnly";

public static final String INTEGRATION_TEST_TASK_NAME = "quarkusIntTest";
public static final String INTEGRATION_TEST_SOURCE_SET_NAME = "integrationTest";
public static final String INTEGRATION_TEST_IMPLEMENTATION_CONFIGURATION_NAME = "integrationTestImplementation";
public static final String INTEGRATION_TEST_RUNTIME_ONLY_CONFIGURATION_NAME = "integrationTestRuntimeOnly";

private final ToolingModelBuilderRegistry registry;

@Inject
Expand Down Expand Up @@ -221,19 +228,19 @@ public void execute(Task test) {

SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class)
.getSourceSets();
SourceSet nativeTestSourceSet = sourceSets.create(NATIVE_TEST_SOURCE_SET_NAME);

SourceSet mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
SourceSet testSourceSet = sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME);

quarkusGenerateCode.configure(task -> task.setSourcesDirectories(getSourcesParents(mainSourceSet)));
quarkusGenerateCodeDev.configure(task -> task.setSourcesDirectories(getSourcesParents(mainSourceSet)));
quarkusGenerateCodeTests.configure(task -> task.setSourcesDirectories(getSourcesParents(testSourceSet)));

SourceSet nativeTestSourceSet = sourceSets.create(NATIVE_TEST_SOURCE_SET_NAME);
nativeTestSourceSet.setCompileClasspath(
nativeTestSourceSet.getCompileClasspath()
.plus(mainSourceSet.getOutput())
.plus(testSourceSet.getOutput()));

nativeTestSourceSet.setRuntimeClasspath(
nativeTestSourceSet.getRuntimeClasspath()
.plus(mainSourceSet.getOutput())
Expand All @@ -244,6 +251,24 @@ public void execute(Task test) {
testNative.setShouldRunAfter(Collections.singletonList(tasks.findByName(JavaPlugin.TEST_TASK_NAME)));
});

SourceSet intTestSourceSet = sourceSets.create(INTEGRATION_TEST_SOURCE_SET_NAME);
intTestSourceSet.setCompileClasspath(
intTestSourceSet.getCompileClasspath()
.plus(mainSourceSet.getOutput())
.plus(testSourceSet.getOutput()));
intTestSourceSet.setRuntimeClasspath(
intTestSourceSet.getRuntimeClasspath()
.plus(mainSourceSet.getOutput())
.plus(testSourceSet.getOutput()));

tasks.register(INTEGRATION_TEST_TASK_NAME, Test.class, intTestTask -> {
intTestTask.setGroup("verification");
intTestTask.setDescription("Runs Quarkus integration tests");
intTestTask.dependsOn(quarkusBuild, tasks.named(JavaBasePlugin.CHECK_TASK_NAME));
intTestTask.setClasspath(intTestSourceSet.getRuntimeClasspath());
intTestTask.setTestClassesDirs(intTestSourceSet.getOutput().getClassesDirs());
});

tasks.withType(Test.class).forEach(configureTestTask);
tasks.withType(Test.class).whenTaskAdded(configureTestTask::accept);

Expand Down Expand Up @@ -279,6 +304,12 @@ private void createConfigurations(Project project) {
configContainer.maybeCreate(NATIVE_TEST_RUNTIME_ONLY_CONFIGURATION_NAME)
.extendsFrom(configContainer.findByName(JavaPlugin.TEST_RUNTIME_ONLY_CONFIGURATION_NAME));

// create a custom configuration to be used for the dependencies of the quarkusIntTest task
configContainer.maybeCreate(INTEGRATION_TEST_IMPLEMENTATION_CONFIGURATION_NAME)
.extendsFrom(configContainer.findByName(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME));
configContainer.maybeCreate(INTEGRATION_TEST_RUNTIME_ONLY_CONFIGURATION_NAME)
.extendsFrom(configContainer.findByName(JavaPlugin.TEST_RUNTIME_ONLY_CONFIGURATION_NAME));

ApplicationDeploymentClasspathBuilder.initConfigurations(project);
}

Expand Down
12 changes: 12 additions & 0 deletions docs/src/main/asciidoc/gradle-tooling.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,18 @@ quarkus {
====

== Running integration tests

Quarkus integration tests (annotated with `@QuarkusIntegrationTest`) will run on the artifact produced by Quarkus.
Those tests can be placed in a `src/integrationTest/java` directory and executed using:

[source, bash]
----
./gradlew quarkusIntTest
----

This task depends on both `check` and `quarkusBuild` tasks. The final artifact will be produced before running tests.

== Using fast-jar

`fast-jar` is now the default quarkus package type. The result of `./gradlew build` command is a new directory under `build` named `quarkus-app`.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
plugins {
id 'java'
id 'io.quarkus'
}

repositories {
// in case a custom local repo is configured we are going to use that instead of the default mavenLocal()
if (System.properties.containsKey('maven.repo.local')) {
maven {
url System.properties.get('maven.repo.local')
}
} else {
mavenLocal()
}
mavenCentral()
}

dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation 'io.quarkus:quarkus-resteasy'

testImplementation 'io.quarkus:quarkus-junit5'
testImplementation 'io.rest-assured:rest-assured'
}

group 'org.acme'
version '1.0.0-SNAPSHOT'

compileJava {
options.encoding = 'UTF-8'
options.compilerArgs << '-parameters'
}

compileTestJava {
options.encoding = 'UTF-8'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
quarkusPlatformArtifactId=quarkus-bom
quarkusPlatformGroupId=io.quarkus
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
pluginManagement {
repositories {
// in case a custom local repo is configured we are going to use that instead of the default mavenLocal()
if (System.properties.containsKey('maven.repo.local')) {
maven {
url System.properties.get('maven.repo.local')
}
} else {
mavenLocal()
}
mavenCentral()
gradlePluginPortal()
}
plugins {
id 'io.quarkus' version "${quarkusPluginVersion}"
}
}
rootProject.name='code-with-quarkus'
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.acme;

import io.quarkus.test.junit.QuarkusIntegrationTest;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;

@QuarkusIntegrationTest
public class ExampleResourceIT extends ExampleResourceTest {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.acme;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class ExampleResource {


@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello World";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.acme;

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;

@QuarkusTest
public class ExampleResourceTest {

@Test
public void testHelloEndpoint() {
given()
.when().get("/hello")
.then()
.statusCode(200)
.body(is("Hello World"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.gradle;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

import java.io.File;

import org.junit.jupiter.api.Test;

public class IntegrationTestBuildTest extends QuarkusGradleWrapperTestBase {

@Test
public void shouldRunIntegrationTestAsPartOfBuild() throws Exception {
File projectDir = getProjectDir("it-test-basic-project");

BuildResult buildResult = runGradleWrapper(projectDir, "clean", "quarkusIntTest");

assertThat(buildResult.getTasks().get(":test")).isEqualTo(BuildResult.SUCCESS_OUTCOME);
assertThat(buildResult.getTasks().get(":check")).isEqualTo(BuildResult.SUCCESS_OUTCOME);
assertThat(buildResult.getTasks().get(":quarkusIntTest")).isEqualTo(BuildResult.SUCCESS_OUTCOME);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ public void shouldRunTest() throws Exception {
final BuildResult buildResult = runGradleWrapper(projectDir, ":clean", ":test");

assertThat(buildResult.getTasks().get(":test")).isEqualTo(BuildResult.SUCCESS_OUTCOME);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ private static Path determineBuildOutputDirectory(final URL url) {
if (url.getPath().endsWith("test-classes/")) {
// we have the maven test classes dir
return toPath(url).getParent();
} else if (url.getPath().endsWith("test/")) {
} else if (url.getPath().endsWith("test/") || url.getPath().endsWith("integrationTest/")) {
// we have the gradle test classes dir, build/classes/java/test
return toPath(url).getParent().getParent().getParent();
} else if (url.getPath().contains("/target/surefire/")) {
Expand Down

0 comments on commit b718fba

Please sign in to comment.