Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/intershopcommunicationsag/test-gradle-plugin

Gradle test plugin - test extension for Gradle plugin builds
https://github.com/intershopcommunicationsag/test-gradle-plugin

development-tools gradle testing-tools

Last synced: 2 months ago
JSON representation

Gradle test plugin - test extension for Gradle plugin builds

Awesome Lists containing this project

README

        

= Gradle Test Plugin
:latestRevision: 4.1.0

[CAUTION]
====
**Breaking Changes!**

This library requires **Gradle >= 8.4** to work properly.
====

== Summary
This library serves some functionality for Gradle plugin builds.
It contains some helper classes, methods and a Spock extension 'TestDir' for test directories.

== Usage
To use the Gradle Test Plugin, add the following lines to your build script:

[source,kotlin,subs="attributes"]
----

tasks {
withType().configureEach {
//Set supported Gradle version
systemProperty("intershop.gradle.versions", "8.4,8.5,8.10.2")
//working dir for tests
systemProperty("intershop.test.base.dir", project.layout.buildDirectory.get().dir("test-working").asFile.absolutePath)
}
}

dependencies {
testImplementation("com.intershop.gradle.test:test-gradle-plugin:{latestRevision}")
}

----

=== Basic Test Classes

==== Abstract Integration Test
Extend your integration test with `com.intershop.gradle.test.AbstractIntegrationGroovySpec` for Groovy based build scripts,
for Kotlin based scripts it is necessary to use `com.intershop.gradle.test.AbstractIntegrationKotlinSpec`:

[source,groovy,subs="attributes"]
----
import com.intershop.gradle.test.AbstractIntegrationGroovySpec

class IntegrationTestSpec extends AbstractIntegrationGroovySpec {
...
}
----

[source,groovy,subs="attributes"]
----
import com.intershop.gradle.test.AbstractIntegrationKotlinSpec

class IntegrationTestSpec extends AbstractIntegrationKotlinSpec {
...
}
----

`AbstractIntegrationGroovySpec` and `AbstractIntegrationKotlinSpec` extends `AbstractIntegrationSpec` which extends `spock.lang.Specification`.

This abstract class comes with some helper methodes, the definition of a project folder, the base definition of the build file and the classpath for GradleRunner (see https://docs.gradle.org/current/userguide/test_kit.html):

[cols="17%,17%,17%,49%", width="95%", options="header"]
|===
|Variable | Type | Default Value | Description

|*testProjectDir* |`File` | /test-working// | The base directory of the test project (blank space is replaced with a dash)
|*buildFile* |`File` | /build.gradle | The build file of the test project
|*pluginClasspath*|`List` | | List of all runtime dependency files prepared by `'createClasspathManifest'` task
|===

[cols="17%,17%,20%,45%", width="95%", options="header"]
|===
|Methods | Type | Parameters | Description

|*getPreparedGradleRunner* | `GradleRunner` | | Returns a GradleRunner created with base project dir (testProjectDir) and the classpath (pluginClasspath)
|*getSupportedGradleVersions* | List | | Returns a list of strings created from the system property `'intershop.gradle.versions'`

|*writeJavaTestClass* |`File` | String packageDotted +
File baseDir = testProjectDir | Creates a "Hello World" Java source file in the standard source directory (`src/main/java`) with the specified package. Without a specified `baseDir` parameter it creates the source file for a single Java Gradle project. It returns the source file itself.

|*writeGroovyTestClass* |`File` | String packageDotted +
File baseDir = testProjectDir | Creates a "Hello World" Groovy source file in the standard source directory (`src/main/groovy`) with the specified package. Without a specified `baseDir` parameter it creates the source file for a single Groovy Gradle project. It returns the source file itself.

|*createSubProject* |`File`| String projectPath +
File settingsGradle +
def buildFileContent | Creates a subproject with path, e.g., `'test1:test2'`. The return value contains the directory of the subproject.

|*writeJavaTestClassTest* |`File` | String packageDotted +
boolean failTest = false +
File baseDir = testProjectDir | Creates a "Hello World Test" Java source file in the standard source directory (`src/test/java`) with the specified package. Without a specified `baseDir` parameter it creates the source file for a single Java Gradle project. Per default the test finished successful, if you set `failTest` to `true` the test will fail. It returns the source file itself.

|*writeGroovyTestClassSpec* |`File` | String packageDotted +
boolean failTest = false +
File baseDir = testProjectDir | Creates a "Hello World Spec" Groovy test spec in the standard source directory (`src/test/groovy`) with the specified package. Without a specified `baseDir` parameter it creates the source file for a single Java Gradle project. Per default the test finished successful, if you set `failTest` to `true` the test will fail. It returns the source file itself. *Note* It is necessery to specify dependencies for the build file!

|*file* |`File` | String path +
File baseDir = testProjectDir | Creates a file in the specified path in the base project dir. Without a specified `baseDir` parameter it creates the file with the specified path in a single project dir.

|*directory* |`File` | String path +
File baseDir = testProjectDir | Creates a directory in the specified path in the base project dir. Without a specified `baseDir` parameter it creates the directory with the specified path in a single project dir.

|*copyResources* |`void` | String srcDir +
String target = '' +
File baseDir = testProjectDir | Copies directories with files from test resources.
|===

[source,groovy,subs="attributes"]
.example.groovy
----
package com.package.test

import com.intershop.gradle.test.AbstractIntegrationGroovySpec
import org.gradle.testkit.runner.GradleRunner
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS

class IntegrationPluginSpec extends AbstractIntegrationGroovySpec {

def 'test description'() {
given:
writeJavaTestClass('com.test.package.test')
writeJavaTestClassTest('com.test.package.test')

buildFile << """
plugins {
id 'java'
}

group = 'com.test'
version = '1.0.0'

sourceCompatibility = 11
targetCompatibility = 11

dependencies {
testCompile 'junit:junit:4.13'
}

repositories {
jcenter()
}
""".stripIndent()

when:
def result = preparedGradleRunner
.withArguments('test', '--stacktrace', '-i')
.withGradleVersion(gradleVersion)
.build()

then:
result.task(':test').outcome == SUCCESS

where:
gradleVersion << supportedGradleVersions
}
----

For the use of the method `'supportedGradleVersions'` it is necessary to specify the system property `'intershop.gradle.versions'`:

[source,groovy,subs="attributes"]
.build.gradle
----
...

test {
// Gradle versions for test
systemProperty 'intershop.gradle.versions', '7.0'
systemProperty 'intershop.test.base.dir', (new File(project.buildDir, 'test-working')).absolutePath
}

dependencies {
classpath 'com.intershop.gradle.test:test-gradle-plugin:{latestRevision}'
compile gradleTestKit()
}

...
----

==== Basic Project Plugin Test

Basic plugin tests are integrated in `com.intershop.gradle.test.AbstractProjectSpec`. This class should be used as a base class for additional extended plugin tests.

[source,groovy,subs="attributes"]
----
import com.intershop.gradle.test.AbstractProjectSpec

class ProjectTestSpec extends AbstractProjectSpec {

@Override
Plugin getPlugin() {
return new 'Plugin Class'()
}

...
}
----

`AbstractProjectSpec` extends `spock.lang.Specification`.

This abstract class adds some special tests for plugins:

[cols="100%", width="70%", options="header"]
|===
|Test
|`'apply does not throw exceptions'`
|`'apply is idempotent'`
|`'apply is fine on all levels of multiproject'`
|`'apply to multiple subprojects'`
|===

The class provides the following variables:

[cols="17%,17%,17%,49%", width="100%, options="header"]
|===
|Variable | Type | Default Value | Description

|*testProjectDir* |`File` | /test-working// | The base directory of the test project (blank space is replaced with a dash)
|*testName* |`org.junit.rules.TestName` | | The test name
|*canonicalName* |`String` | | The test name without spaces (blank space is replaced with a dash)
|*project* |`Project` | | The test root project
|===

This class is a fork from Netflix nebula-test extension.

=== Test Directory Spock Extension @TestDir

Used on a File property of a spec class this annotation will cause a temporary directory to be created and injected for the spec before the first feature method is run.
The directory will be deleted if exists before it is created again for the spec.

The baseDir is without any special configuration taken from the test system property `'intershop.test.base.dir'`. The default root path is `'build/test-working'`.

[cols="17%,17%,17%,49%", width="95%", options="header"]
|===
| Methods | Type | Default Value |

| *baseDir* | `String` | '' | Base dir of the directory
| *clean* | `boolean` | `true` | Deletes the directory before test starts
| *overwrite* | `boolean` | `false`| If `clean` is `false`, and this value is also `false` the folder will be extended with a number.
| *useTempDirAsBase* | `boolean` | `false`| Instead of `'intershop.test.base.dir'` the value of `'java.io.tmpdir'` is used for the base dir.
| *large* | `boolean` | `false`| If set the test directory is expected to be large and is cleaned using OS commands. +
*CAUTION*: This does not work for long directories on Windows.
|===

=== Assertions

This adds supplementary assertions for tests.

[source,groovy,subs="attributes"]
----
import spock.lang.Specification

import static com.intershop.gradle.test.util.Assertions.*

class Spec extends Specification {

def "file contains content"() {
when:
File f = new File("test.file")
String c = "test.content"
f.setText(c)

then:
fileHasContent(f, 'test content')
}

def "file does not contain failures"() {
when:
File f = new File("test.file")
f << """Text that does not contain any messages
indicating failures at all"""

then:
isErrorFree('some context', text, ['error','exception'])
}

def "content does not contain failures"() {
when:
String text = """Text that does not contain any messages
indicating failures at all"""

then:
isErrorFree('some context', text, ['error','exception'])
}

...
}
----

For more information see assigned Groovy doc.

=== Repository Builder

==== Ivy Repository Builder

This builder creates a simply Ivy repository based on Ivy and artifact pattern.

[source,groovy,subs="attributes"]
----
import com.intershop.gradle.test.builder.TestIvyRepoBuilder

String writeIvyRepo(File dir) {
File repoDir = new File(dir, 'repo')

new TestIvyRepoBuilder().repository (ivyPattern: ivyPattern, artifactPattern: artifactPattern) {

module(org: 'com.company', name: 'module', rev: '1.0.0') {
dependency org: 'com.company', name: 'dep1', rev: '1.0.0'
dependency org: 'com.company', name: 'dep2', rev: '1.0.0'
dependency org: 'com.company', name: 'dep3', rev: '1.0.0'
}
module(org: 'com.company', name: 'dep1', rev: '1.0.0')
module(org: 'com.company', name: 'dep2', rev: '1.0.0')
module(org: 'com.company', name: 'dep3', rev: '1.0.0')

}.writeTo(testDir)
}
----

For more information see assigned Groovy doc.

==== Maven Repository Builder

This builder creates a simply Maven repository.

[source,groovy,subs="attributes"]
----
import com.intershop.gradle.test.builder.TestMavenRepoBuilder

String writeMavenRepo(File dir) {
File repoDir = new File(dir, 'repo')

new TestMavenRepoBuilder().repository {
project(artifactId:'foo') {
dependency(artifactId:'dep')
}
project(artifactId:'bar', packaging:'pkg', classifier:'cls') {
module('sub1')
module('sub2')
parent(artifactId:'par', relativePath:'relPath')
dependency(artifactId:'dep1', classifier:'cls', scope:'scope', type:'typ', optional:true)
dependency(artifactId:'dep2', optional:false)

artifact('content')
artifact {
file(path:'foo/bar', 'bazzzz')
}
artifact(classifier:'javadoc') {
dir('foo/baz')
}
}
}.writeTo(testDir)
}
----

For more information see assigned Groovy doc.

== Java Doc

For more information please check the provided Java doc.

== Contribute

See link:https://github.com/IntershopCommunicationsAG/.github/blob/main/CONTRIBUTE.asciidoc[here] for details.

== License

Copyright 2014-2016 Intershop Communications.

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

http://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.