main.name.remal.gradle_plugins.plugins.testing.RandomizeTestClassesPlugin.kt Maven / Gradle / Ivy
package name.remal.gradle_plugins.plugins.testing
import name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin
import name.remal.gradle_plugins.dsl.CreateExtensionsPluginAction
import name.remal.gradle_plugins.dsl.Plugin
import name.remal.gradle_plugins.dsl.PluginAction
import name.remal.gradle_plugins.dsl.SimpleTestAdditionalGradleScript
import name.remal.gradle_plugins.dsl.extensions.all
import name.remal.gradle_plugins.dsl.extensions.doFirstOrdered
import name.remal.gradle_plugins.dsl.extensions.get
import name.remal.gradle_plugins.dsl.extensions.logLifecycle
import name.remal.gradle_plugins.dsl.extensions.randomizeFileTree
import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionContainer
import org.gradle.api.tasks.TaskContainer
import org.gradle.api.tasks.testing.Test
import java.util.Random
private const val PLUGIN_ID = "name.remal.randomize-test-classes"
@Plugin(
id = PLUGIN_ID,
description = "Plugin that randomizes test classes for every Test task run.",
tags = ["test", "random"]
)
@SimpleTestAdditionalGradleScript(
"""
apply plugin: 'java'
dependencies {
testImplementation "junit:junit:4.12"
}
List testClasses = (1..9).collect { "name.remal.test.TestClass${'$'}it" }
File executedTestClassesFile = file(".executed-classes")
executedTestClassesFile.parentFile.mkdirs()
executedTestClassesFile.delete()
test {
useJUnit()
forkEvery = 0
maxParallelForks = 1
doLast {
if (!executedTestClassesFile.isFile()) {
throw new AssertionError("${'$'}executedTestClassesFile is not a file")
}
List executedTestClasses = executedTestClassesFile.readLines("UTF-8")
.collect { it.trim() }
.findAll { !it.isEmpty() }
if (executedTestClasses == testClasses) {
throw new AssertionError("${'$'}executedTestClasses == ${'$'}testClasses")
}
if (executedTestClasses.size() != testClasses.size()) {
throw new AssertionError("executedTestClasses.size() != testClasses.size()")
}
}
}
testClassesRandomization {
seed = 1
}
testClasses.forEach { className ->
project.file("src/test/java/${'$'}{className.replace('.', '/')}.java").with {
parentFile.mkdirs()
newWriter().withCloseable {
it.println "package ${'$'}{className.substring(0, className.lastIndexOf('.'))};"
it.println ""
it.println "import java.io.File;"
it.println ""
it.println "import org.junit.Test;"
it.println ""
it.println "import static java.nio.file.Files.*;"
it.println "import static java.nio.file.StandardOpenOption.*;"
it.println "import static java.util.Arrays.*;"
it.println ""
it.println "public class ${'$'}{className.substring(className.lastIndexOf('.') + 1)} {"
it.println ""
it.println " @Test"
it.println " public void test() throws Throwable {"
it.println " write(new File(\"${'$'}{executedTestClassesFile.absolutePath.replace('\\', '\\\\')}\").toPath(), asList(\"${'$'}className\"), CREATE, APPEND);"
it.println " }"
it.println ""
it.println "}"
}
}
}
"""
)
class RandomizeTestClassesPlugin : BaseReflectiveProjectPlugin() {
@CreateExtensionsPluginAction
fun ExtensionContainer.`Create 'testClassesRandomization' extension`(project: Project) {
create("testClassesRandomization", RandomizeTestClassesExtension::class.java, project)
}
@PluginAction
fun TaskContainer.`Process all Test tasks`(extensions: ExtensionContainer) {
val settings = extensions[RandomizeTestClassesExtension::class.java]
val seed: Long by lazy { settings.seed }
all(Test::class.java) {
it.doFirstOrdered { task ->
if (!settings.enabled) {
logger.debug("Test classes randomization is disabled")
return@doFirstOrdered
}
task.logLifecycle("Plugin {}: randomizing test classes using seed {}", pluginId, seed)
task.testClassesDirs = task.project.randomizeFileTree(task.candidateClassFiles, Random(seed))
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy