generated from micronaut-projects/micronaut-project-template
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a
TestResourcesScope
annotation (#241)
By default, test resources are shared between all tests. This means, in particular, that a single container will be spawned if multiple tests require the same property. For example, we would have a single MySQL container for the whole test suite, which makes testing significantly faster, avoiding containers to be started and shutdown in each test. However, in some situations it may be required to isolate tests from each other, and a test may want to work with its own, isolated container. This commit introduces a new `TestResourcesScope` annotation which can be put added at a _test class_ level, which defines the scope of the test resources used in that test. A scope can be shared by multiple tests, and you can see the general case (all tests share the same resources) as the "root scope". A scope is closed whenever the last test which works in that scope is finished. Before, doing this required assigning a test property to the test and manually counting the number of tests which are executed, then calling the test resources client directly when all tests are executed, which is both error prone and imprecise (in case only a subset of the tests are executed). Because of implementation limitations, the way the scope is recognized is by using a thread local, which has a couple consequences: 1. it only works properly if tests are executed in a _single_ JVM. 2. tests which use custom threads and execute the application in that thread wouldn't see the scope and have to rely on using the client
- Loading branch information
Showing
42 changed files
with
1,338 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
...es/META-INF/native-image/micronaut-test-resources-extensions-core/native-image.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Args = --initialize-at-run-time=io.micronaut.test.extensions.testresources.TestResourcesClientHolder |
60 changes: 60 additions & 0 deletions
60
test-resources-extensions/test-resources-extensions-junit-platform/build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
plugins { | ||
id 'io.micronaut.build.internal.test-resources-mntest-extension' | ||
id 'jvm-test-suite' | ||
id("org.jetbrains.kotlin.jvm") version "1.8.21" | ||
id("com.google.devtools.ksp") version "1.8.21-1.0.11" | ||
} | ||
|
||
description = """ | ||
Provides JUnit 5 extensions to extend the capabiities of tests when | ||
test resources are present. | ||
""" | ||
|
||
testing { | ||
suites { | ||
spockTest(JvmTestSuite) { | ||
dependencies { | ||
implementation project(project.path) | ||
implementation testFixtures(project(project.path)) | ||
implementation(mnTest.micronaut.test.spock) | ||
compileOnly(mn.micronaut.inject.groovy) | ||
} | ||
targets.all { | ||
tasks.named("check") { | ||
dependsOn(testTask) | ||
} | ||
} | ||
} | ||
koTest(JvmTestSuite) { | ||
dependencies { | ||
implementation project(project.path) | ||
implementation testFixtures(project(project.path)) | ||
implementation(mnTest.micronaut.test.kotest5) | ||
} | ||
targets.all { | ||
tasks.named("check") { | ||
dependsOn(testTask) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
dependencies { | ||
annotationProcessor(mn.micronaut.inject.java) | ||
api(projects.micronautTestResourcesExtensionsCore) | ||
api(projects.micronautTestResourcesClient) | ||
implementation(libs.junit.jupiter.api) | ||
implementation(libs.junit.platform.launcher) | ||
testAnnotationProcessor(mn.micronaut.inject.java) | ||
testImplementation(mnTest.micronaut.test.junit5) | ||
testFixturesAnnotationProcessor(mn.micronaut.inject.java) | ||
testFixturesApi(libs.junit.platform.launcher) | ||
testFixturesApi(platform(mnTest.micronaut.test.bom)) | ||
testFixturesImplementation(projects.micronautTestResourcesClient) | ||
testFixturesImplementation(projects.micronautTestResourcesExtensionsCore) | ||
testRuntimeOnly(libs.junit.jupiter.engine) | ||
testRuntimeOnly(mn.micronaut.context) | ||
testRuntimeOnly(mn.snakeyaml) | ||
kspKoTest(mn.micronaut.inject.kotlin) | ||
} |
27 changes: 27 additions & 0 deletions
27
...unit-platform/src/koTest/kotlin/io/micronaut/test/extensions/junit5/AbstractScopedTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright 2003-2021 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.test.extensions.junit5 | ||
|
||
import io.kotest.core.spec.Spec | ||
import io.kotest.core.spec.style.StringSpec | ||
import io.micronaut.test.extensions.testresources.junit5.FakeTestResourcesClient | ||
import org.junit.jupiter.api.AfterAll | ||
|
||
abstract class AbstractScopedTest(body: StringSpec.() -> Unit = {}) : StringSpec(body) { | ||
override fun afterSpec(f: suspend (Spec) -> Unit) { | ||
FakeTestResourcesClient.reset() | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
...ns-junit-platform/src/koTest/kotlin/io/micronaut/test/extensions/junit5/ClassScopeTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* Copyright 2003-2021 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.test.extensions.junit5 | ||
|
||
import io.kotest.matchers.shouldBe | ||
import io.micronaut.test.extensions.junit5.annotation.ScopeNamingStrategy | ||
import io.micronaut.test.extensions.junit5.annotation.TestResourcesScope | ||
import io.micronaut.test.extensions.kotest5.annotation.MicronautTest | ||
|
||
@MicronautTest | ||
@TestResourcesScope(namingStrategy = ScopeNamingStrategy.TestClassName::class) | ||
internal class ClassScopeTest : ParentTestWithScope({ | ||
"scope name is the current test class name"() { | ||
ScopeHolder.get().orElse(null) shouldBe ClassScopeTest::class.java.name | ||
} | ||
}) |
28 changes: 28 additions & 0 deletions
28
...unit-platform/src/koTest/kotlin/io/micronaut/test/extensions/junit5/InheritedScopeTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright 2003-2021 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.test.extensions.junit5 | ||
|
||
import io.kotest.matchers.shouldBe | ||
import io.micronaut.test.extensions.kotest5.annotation.MicronautTest | ||
|
||
@MicronautTest | ||
internal class InheritedScopeTest : ParentTestWithScope({ | ||
|
||
"scope from parent class is visible" { | ||
ScopeHolder.get().orElse(null) shouldBe "from parent" | ||
} | ||
|
||
}) |
29 changes: 29 additions & 0 deletions
29
...-junit-platform/src/koTest/kotlin/io/micronaut/test/extensions/junit5/PackageScopeTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* Copyright 2003-2021 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.test.extensions.junit5 | ||
|
||
import io.kotest.matchers.shouldBe | ||
import io.micronaut.test.extensions.junit5.annotation.ScopeNamingStrategy | ||
import io.micronaut.test.extensions.junit5.annotation.TestResourcesScope | ||
import io.micronaut.test.extensions.kotest5.annotation.MicronautTest | ||
|
||
@MicronautTest | ||
@TestResourcesScope(namingStrategy = ScopeNamingStrategy.PackageName::class) | ||
internal class PackageScopeTest : ParentTestWithScope({ | ||
"scope name is the current package" { | ||
ScopeHolder.get().orElse(null) shouldBe PackageScopeTest::class.java.packageName | ||
} | ||
}) |
22 changes: 22 additions & 0 deletions
22
...nit-platform/src/koTest/kotlin/io/micronaut/test/extensions/junit5/ParentTestWithScope.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* Copyright 2003-2021 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.test.extensions.junit5 | ||
|
||
import io.kotest.core.spec.style.StringSpec | ||
import io.micronaut.test.extensions.junit5.annotation.TestResourcesScope | ||
|
||
@TestResourcesScope("from parent") | ||
internal abstract class ParentTestWithScope(body: StringSpec.() -> Unit = {}) : AbstractScopedTest(body) |
45 changes: 45 additions & 0 deletions
45
...ensions-junit-platform/src/main/java/io/micronaut/test/extensions/junit5/ScopeHolder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright 2017-2021 original authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.test.extensions.junit5; | ||
|
||
import io.micronaut.core.annotation.Internal; | ||
|
||
import java.util.Optional; | ||
|
||
/** | ||
* Our JUnit listener needs to communicate with the test resources | ||
* provider factory. Because they are both instantiated with | ||
* service loading, we are using a thread local to share information. | ||
*/ | ||
@Internal | ||
final class ScopeHolder { | ||
private static final ThreadLocal<String> CURRENT_SCOPE = ThreadLocal.withInitial(() -> null); | ||
|
||
private ScopeHolder() { | ||
} | ||
|
||
public static Optional<String> get() { | ||
return Optional.ofNullable(CURRENT_SCOPE.get()); | ||
} | ||
|
||
public static void set(String scope) { | ||
CURRENT_SCOPE.set(scope); | ||
} | ||
|
||
public static void remove() { | ||
CURRENT_SCOPE.remove(); | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
...m/src/main/java/io/micronaut/test/extensions/junit5/ScopeTestPropertyProviderFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* Copyright 2017-2021 original authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.test.extensions.junit5; | ||
|
||
import io.micronaut.test.support.TestPropertyProvider; | ||
import io.micronaut.test.support.TestPropertyProviderFactory; | ||
import io.micronaut.testresources.core.Scope; | ||
|
||
import java.util.Map; | ||
|
||
public class ScopeTestPropertyProviderFactory implements TestPropertyProviderFactory { | ||
@Override | ||
public TestPropertyProvider create(Map<String, Object> availableProperties, Class<?> testClass) { | ||
return () -> ScopeHolder.get() | ||
.map(value -> Map.of(Scope.PROPERTY_KEY, value)) | ||
.orElseGet(Map::of); | ||
} | ||
|
||
} |
Oops, something went wrong.