From a7f631db287dab888336d83c9544242ec8d91530 Mon Sep 17 00:00:00 2001 From: Jose Date: Mon, 31 Jul 2023 14:41:41 +0200 Subject: [PATCH] Properly resolve `@TestProfile` when using nested tests in base classes Fix https://github.com/quarkusio/quarkus/issues/35104 --- .../io/quarkus/it/main/CommonNestedTest.java | 27 +++++++++++++ .../QuarkusTestNested1WithCommonCaseTest.java | 14 +++++++ .../QuarkusTestNested2WithCommonCaseTest.java | 7 ++++ .../AbstractJvmQuarkusTestExtension.java | 39 ++++++++++++++++++- 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 integration-tests/main/src/test/java/io/quarkus/it/main/CommonNestedTest.java create mode 100644 integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestNested1WithCommonCaseTest.java create mode 100644 integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestNested2WithCommonCaseTest.java diff --git a/integration-tests/main/src/test/java/io/quarkus/it/main/CommonNestedTest.java b/integration-tests/main/src/test/java/io/quarkus/it/main/CommonNestedTest.java new file mode 100644 index 00000000000000..2386572339848d --- /dev/null +++ b/integration-tests/main/src/test/java/io/quarkus/it/main/CommonNestedTest.java @@ -0,0 +1,27 @@ +package io.quarkus.it.main; + +import static org.hamcrest.Matchers.is; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import io.restassured.RestAssured; + +public abstract class CommonNestedTest { + + public String defaultProfile() { + return "Hello"; + } + + @Nested + class NestedTests { + @Test + public void testProfileFromNested() { + RestAssured.when() + .get("/greeting/Stu") + .then() + .statusCode(200) + .body(is(defaultProfile() + " Stu")); + } + } +} diff --git a/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestNested1WithCommonCaseTest.java b/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestNested1WithCommonCaseTest.java new file mode 100644 index 00000000000000..0cfa049d1d6e3f --- /dev/null +++ b/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestNested1WithCommonCaseTest.java @@ -0,0 +1,14 @@ +package io.quarkus.it.main; + +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestProfile(QuarkusTestNestedWithTestProfileTestCase.OuterProfile.class) +public class QuarkusTestNested1WithCommonCaseTest extends CommonNestedTest { + + @Override + public String defaultProfile() { + return "OuterProfile"; + } +} diff --git a/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestNested2WithCommonCaseTest.java b/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestNested2WithCommonCaseTest.java new file mode 100644 index 00000000000000..a81f3bbbaeba79 --- /dev/null +++ b/integration-tests/main/src/test/java/io/quarkus/it/main/QuarkusTestNested2WithCommonCaseTest.java @@ -0,0 +1,7 @@ +package io.quarkus.it.main; + +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class QuarkusTestNested2WithCommonCaseTest extends CommonNestedTest { +} diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java index af079e89bb715c..3c343ab970eaf6 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java @@ -13,12 +13,14 @@ import java.util.Deque; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.function.Consumer; import java.util.stream.Collectors; import jakarta.enterprise.inject.Alternative; import org.jboss.jandex.Index; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.extension.ExtensionContext; import io.quarkus.bootstrap.BootstrapConstants; @@ -213,7 +215,42 @@ private ApplicationModel getGradleAppModelForIDE(Path projectRoot) throws IOExce } protected Class getQuarkusTestProfile(ExtensionContext extensionContext) { - Class testClass = extensionContext.getRequiredTestClass(); + // If the current class or any enclosing class in its hierarchy is annotated with `@TestProfile`. + Class testProfile = findTestProfileAnnotation(extensionContext.getRequiredTestClass()); + if (testProfile != null) { + return testProfile; + } + + // Otherwise, if the current class is annotated with `@Nested`: + if (extensionContext.getRequiredTestClass().isAnnotationPresent(Nested.class)) { + // let's try to find the `@TestProfile` from the enclosing classes: + testProfile = findTestProfileAnnotation(extensionContext.getRequiredTestClass().getEnclosingClass()); + if (testProfile != null) { + return testProfile; + } + + // if not found, let's try the parents + Optional parentContext = extensionContext.getParent(); + while (parentContext.isPresent()) { + ExtensionContext currentExtensionContext = parentContext.get(); + if (currentExtensionContext.getTestClass().isEmpty()) { + break; + } + + testProfile = findTestProfileAnnotation(currentExtensionContext.getTestClass().get()); + if (testProfile != null) { + return testProfile; + } + + parentContext = currentExtensionContext.getParent(); + } + } + + return null; + } + + private Class findTestProfileAnnotation(Class clazz) { + Class testClass = clazz; while (testClass != null) { TestProfile annotation = testClass.getAnnotation(TestProfile.class); if (annotation != null) {