Use Gradle Toolkit for testing Gradle plugin

This commit is contained in:
Denis Stepanov
2016-04-20 19:19:32 +02:00
committed by Marcin Grzejszczak
parent bb4df7903a
commit 172d8e73cd
7 changed files with 155 additions and 37 deletions

View File

@@ -1,7 +1,13 @@
package io.codearte.accurest.plugin
import nebula.test.IntegrationSpec
import nebula.test.functional.GradleRunner
import org.apache.commons.io.FileUtils
import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.BuildTask
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import spock.lang.Specification
import java.nio.file.Files
import java.nio.file.Path
@@ -9,19 +15,44 @@ import java.nio.file.Path
import static java.nio.charset.StandardCharsets.UTF_8
/**
* @author Olga Maciaszek-Sharma
* @author Olga Maciaszek-Sharma
* @author Denis Stepanov
* @since 23.02.16
*/
class AccurestIntegrationSpec extends IntegrationSpec {
class AccurestIntegrationSpec extends Specification {
public static final String SPOCK = "targetFramework = 'Spock'"
public static final String JUNIT = "targetFramework = 'JUnit'"
public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'"
public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'"
@Rule
TemporaryFolder testProjectDir = new TemporaryFolder()
void setup() {
classpathFilter = GradleRunner.CLASSPATH_ALL //workaround for removing dependant modules by default filter
}
public static final String SPOCK = "targetFramework = 'Spock'"
public static final String JUNIT = "targetFramework = 'JUnit'"
public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'"
public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'"
protected void setupForProject(String projectRoot) {
copyResourcesToRoot(projectRoot)
def pluginClasspathResource = getClass().classLoader.findResource("plugin-classpath.txt")
if (pluginClasspathResource == null) {
throw new IllegalStateException("Did not find 'plugin-classpath.txt'")
}
String pluginClasspath = pluginClasspathResource.readLines()
.collect { it.replace('\\', '\\\\') } // escape backslashes in Windows paths
.collect { "'$it'" }
.join(", ")
buildFile << """
buildscript {
dependencies {
classpath files($pluginClasspath)
}
}
"""
// Extending buildscript is required when 'apply' is used.
// 'GradleRunner#withPluginClasspath' can be used when plugin is added using 'plugins { id...'
}
protected void switchToJunitTestFramework() {
switchToJunitTestFramework(MVC_SPEC, MVC_TEST)
@@ -34,4 +65,57 @@ class AccurestIntegrationSpec extends IntegrationSpec {
Files.write(path, content.getBytes(UTF_8))
}
protected void runTasksSuccessfully(String... tasks) {
BuildResult result = run(tasks)
result.tasks.each {
assert it.outcome == TaskOutcome.SUCCESS || it.outcome == TaskOutcome.UP_TO_DATE
}
}
protected BuildResult validateTasksOutcome(BuildResult result, TaskOutcome expectedOutcome, String... tasks) {
tasks.each {
BuildTask task = result.task(":" + it)
assert task
assert task.outcome == expectedOutcome
}
return result
}
protected BuildResult run(String... tasks) {
return GradleRunner.create()
.withProjectDir(testProjectDir.root)
.withArguments(tasks)
.build()
}
protected void copyResourcesToRoot(String srcDir) {
copyResources(srcDir, testProjectDir.root)
}
protected void copyResources(String srcDir, File destinationFile) {
ClassLoader classLoader = getClass().getClassLoader()
URL resource = classLoader.getResource(srcDir)
if (resource == null) {
throw new RuntimeException("Could not find classpath resource: $srcDir")
}
File resourceFile = new File(resource.toURI())
if (resourceFile.file) {
FileUtils.copyFile(resourceFile, destinationFile)
} else {
FileUtils.copyDirectory(resourceFile, destinationFile)
}
}
protected File file(String path) {
return new File(testProjectDir.getRoot(), path)
}
protected boolean fileExists(String path) {
return file(path).exists()
}
protected File getBuildFile() {
return new File('build.gradle', testProjectDir.root)
}
}

View File

@@ -1,8 +1,11 @@
package io.codearte.accurest.plugin
import io.codearte.accurest.util.AssertionUtil
import org.gradle.testkit.runner.BuildResult
import spock.lang.Stepwise
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE
@Stepwise
class BasicFunctionalSpec extends AccurestIntegrationSpec {
@@ -12,18 +15,16 @@ class BasicFunctionalSpec extends AccurestIntegrationSpec {
private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/TEST-accurest.twitter_places_analyzer.PairIdSpec.xml"
void setup() {
copyResources("functionalTest/bootSimple", "")
runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it
setupForProject("functionalTest/bootSimple")
runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it
}
def "should pass basic flow"() {
given:
assert fileExists('build.gradle')
def "should pass basic flxow"() {
when:
def result = runTasksSuccessfully('check')
BuildResult result = run("check")
then:
result.wasExecuted(":generateWireMockClientStubs")
result.wasExecuted(":generateAccurest")
result.task(":generateWireMockClientStubs").outcome == SUCCESS
result.task(":generateAccurest").outcome == SUCCESS
and: "tests generated"
fileExists(GENERATED_TEST)
@@ -37,7 +38,7 @@ class BasicFunctionalSpec extends AccurestIntegrationSpec {
def "should generate valid client json stubs for simple input"() {
when:
runTasksSuccessfully('generateWireMockClientStubs')
run('generateWireMockClientStubs')
then:
def generatedClientJsonStub = file(GENERATED_CLIENT_JSON_STUB).text
AssertionUtil.assertThatJsonsAreEqual("""
@@ -73,25 +74,24 @@ class BasicFunctionalSpec extends AccurestIntegrationSpec {
fileExists(GENERATED_TEST)
when: "running generation without change inputs"
def secondExecutionResult = runTasksSuccessfully('generateWireMockClientStubs', 'generateAccurest')
def secondExecutionResult = run('generateWireMockClientStubs', 'generateAccurest')
then: "tasks should be up-to-date"
secondExecutionResult.wasUpToDate(":generateWireMockClientStubs")
secondExecutionResult.wasUpToDate(":generateAccurest")
validateTasksOutcome(secondExecutionResult, UP_TO_DATE, 'generateWireMockClientStubs', 'generateAccurest')
when: "inputs changed"
def groovyDslFile = file(GROOVY_DSL_CONTRACT)
groovyDslFile.text = groovyDslFile.text.replace("200", "599")
and: "tasks run"
def thirdExecutionResult = runTasksSuccessfully('generateWireMockClientStubs', 'generateAccurest')
def thirdExecutionResult = run('generateWireMockClientStubs', 'generateAccurest')
then: "tasks should be reexecuted"
thirdExecutionResult.wasExecuted(":generateWireMockClientStubs")
thirdExecutionResult.wasExecuted(":generateAccurest")
validateTasksOutcome(thirdExecutionResult, SUCCESS, 'generateWireMockClientStubs', 'generateAccurest')
and: "changes visible in generate files"
file(GENERATED_CLIENT_JSON_STUB).text.contains("599")
file(GENERATED_TEST).text.contains("599")
}
}

View File

@@ -6,7 +6,7 @@ import spock.lang.Stepwise
class MessagingProjectSpec extends AccurestIntegrationSpec {
void setup() {
copyResources("functionalTest/messagingProject", "")
setupForProject("functionalTest/messagingProject")
runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it
}

View File

@@ -6,9 +6,8 @@ import spock.lang.Stepwise
class SampleJerseyProjectSpec extends AccurestIntegrationSpec {
void setup() {
copyResources("functionalTest/sampleJerseyProject", "")
runTasksSuccessfully('clean')
//delete accidental output when previously importing SimpleBoot into Idea to tweak it
setupForProject("functionalTest/sampleJerseyProject")
runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it
}
def "should pass basic flow for Spock"() {

View File

@@ -6,7 +6,7 @@ import spock.lang.Stepwise
class SampleProjectSpec extends AccurestIntegrationSpec {
void setup() {
copyResources("functionalTest/sampleProject", "")
setupForProject("functionalTest/sampleProject")
runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it
}

View File

@@ -6,7 +6,7 @@ import spock.lang.Stepwise
class ScenarioProjectSpec extends AccurestIntegrationSpec {
void setup() {
copyResources("functionalTest/scenarioProject", "")
setupForProject("functionalTest/scenarioProject")
runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it
}

View File

@@ -130,9 +130,7 @@ project(':accurest-gradle-plugin') {
compile project(':accurest-converters')
compile gradleApi()
testCompile('com.netflix.nebula:nebula-test:4.0.0') {
exclude(group: 'org.spockframework')
}
testCompile gradleTestKit()
testCompile project(':accurest-testing-utils')
}
@@ -147,13 +145,50 @@ project(':accurest-gradle-plugin') {
}
}
// Hack for reusing this in the plugin test
task createClasspathManifest {
def outputDir = file("$buildDir/$name")
inputs.files sourceSets.main.runtimeClasspath
outputs.dir outputDir
doLast {
outputDir.mkdirs()
file("$outputDir/plugin-classpath.txt").text = sourceSets.test.runtimeClasspath.join("\n")
// Switch to 'sourceSets.main' after 'test.dependsOn's are removed
}
}
test.dependsOn(':accurest-core:install')
test.dependsOn(':accurest-messaging-root:accurest-messaging-core:install')
test.dependsOn(':accurest-messaging-root:accurest-messaging-integration:install')
funcTest.dependsOn(':accurest-core:install')
funcTest.dependsOn(':accurest-messaging-root:accurest-messaging-core:install')
funcTest.dependsOn(':accurest-messaging-root:accurest-messaging-integration:install')
// Add the classpath file to the test runtime classpath
dependencies {
testRuntime files(createClasspathManifest)
}
uploadArchives.dependsOn { funcTest }
}
task wrapper(type: Wrapper) {
gradleVersion = '2.12'
}
// REMOVE AFTER https://issues.gradle.org/browse/GRADLE-3433 IS FIXED
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "gradle.plugin.com.palantir.ideatestfix:gradle-idea-test-fix:0.1.0"
}
}
apply plugin: "com.palantir.idea-test-fix"