# Testing a Settings plugin

**URL:** https://discuss.gradle.org/t/testing-a-settings-plugin/12716
**Category:** Help/Discuss
**Tags:** plugins
**Created:** [November 11, 2015, 9:55pm UTC](https://discuss.gradle.org/t/testing-a-settings-plugin/12716 "2015-11-11T21:55:39Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![Boaz\_Jan](https://avatars.discourse-cdn.com/v4/letter/b/df705f/32.png) [@Boaz\_Jan](https://discuss.gradle.org/u/Boaz_Jan)
#### Post date: [November 11, 2015, 9:55pm UTC](https://discuss.gradle.org/t/testing-a-settings-plugin/12716/1 "2015-11-11T21:55:40Z")

</div>

Hi Gradle folks,

I’ve created a plugin that implements Plugin\<Settings\> and I would like to create some sort of integration test for it.  
Is there something like ProjectBuilder for Settings? I noticed SettingsPluginIntegrationSpec, AbstractIntegrationSpec & AbstractIntergationTest in the gradle integTest project though I found no way to depend on it, apparently it’s not published.

I’ve tried working with gradleTestKit, but even after the classpath manipulation (and the discovery that the old plugin application notation is not supported in the test kit) I found that Settings plugins can only be applied using the old notation.

Is there a way to test Settings plugins without resorting to actually executing gradle outside of test code or replicating the integTest code?

Thanks

---

<div class="post-metadata">

### Author: ![bmuschko](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/bmuschko/32/5458_2.png) [@bmuschko](https://discuss.gradle.org/u/bmuschko)
#### Post date: [November 11, 2015, 10:15pm UTC](https://discuss.gradle.org/t/testing-a-settings-plugin/12716/2 "2015-11-11T22:15:37Z")

</div>

At the moment there’s not a way to create a `Settings` instance like you can create a `Project` instance with the `ProjectBuilder`.

I’d rather go down the TestKit route. You can still apply the plugin with the “old” `apply` notation if you want to. You just need to add the plugin classes to the build script’s classpath manually. Can you explain why it matters to your plugin how it is applied in your test setup?

You can find a bunch of examples for these use cases in [this test class](https://github.com/gradle/gradle/blob/master/subprojects/test-kit/src/integTest/groovy/org/gradle/testkit/TestKitEndUserIntegrationTest.groovy) of ours.

---

<div class="post-metadata">

### Author: ![Boaz\_Jan](https://avatars.discourse-cdn.com/v4/letter/b/df705f/32.png) [@Boaz\_Jan](https://discuss.gradle.org/u/Boaz_Jan)
#### Post date: [November 11, 2015, 11:09pm UTC](https://discuss.gradle.org/t/testing-a-settings-plugin/12716/3 "2015-11-11T23:09:37Z")

</div>

It doesn’t matter.

All the plugin application in that file (other then a test running a task running a standard test) are for the groovy plugin which is implicitly available on all builds, not a custom one.

I followed the classpath manipulation to the letter.  
How would I apply the plugin in the settings?  
`apply plugin: 'someplugin'` resulted at plugin not found.  
`apply plugin: com.something.SomePlugin` resulted at could not find property ‘com’

Checking the plugin-classpath.txt file I see all the relevant jars and /build/classes/main dir and /build/resources/main dir.  
I’ve debbuged the setup code and the DefaultClassPath instance seems to be created successfully.  
I’ve even explicitly added all classes and resources to the plugin-classpath.txt file but to no avail.

Everything works when I test the plugin manually, so it’s not the gradle-plugins manifest.

Is there something I’m missing? should I include some pseudo repository in the settings file before applying the plugin?

My code is essentially a duplicate of the classpath manipulation to the letter.  
The test is as follows

````gradle
buildFile << '''apply plugin: \'java\' 
                    repositories { jcenter() }
                    task nothing << { println 'nothing' }
                  '''
GradleRunner.create().withProjectDir(testDir.getRoot()).withArgument('nothing').withPluginClasspath(pluginClasspath).build()```
````

---

<div class="post-metadata">

### Author: ![bmuschko](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/bmuschko/32/5458_2.png) [@bmuschko](https://discuss.gradle.org/u/bmuschko)
#### Post date: [November 12, 2015, 1:49pm UTC](https://discuss.gradle.org/t/testing-a-settings-plugin/12716/4 "2015-11-12T13:49:44Z")

</div>

I added a [test case to TestKitEndUserIntegrationTest.groovy](https://github.com/gradle/gradle/commit/6b1ced257444b04ca4f93a4e0d624d0f1903e42c) that demonstrates the required setup for testing a `Settings` plugin. Hope this helps.

---

<div class="post-metadata">

### Author: ![Schalk\_Cronje](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/schalk_cronje/32/6511_2.png) [@Schalk\_Cronje](https://discuss.gradle.org/u/Schalk_Cronje)
#### Post date: [November 12, 2015, 3:52pm UTC](https://discuss.gradle.org/t/testing-a-settings-plugin/12716/5 "2015-11-12T15:52:19Z")

</div>

Use the `gradleTest` plugin. Dump a copy of the settings.gradle you want to test with in the `src/gradleTest/TEST_NAME/` folder.

P.S. You can use the `TestKit` API for htis, but you’ll need at least the RC version of 2.9 to have something useful IMHO. For all other cases in this context when you are using an older version of Gradle you are still better off using the `gradleTest` plugin. It has the advantage of testing your plugin against a whole set of Gradle versions.

---

<div class="post-metadata">

### Author: ![bmuschko](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/bmuschko/32/5458_2.png) [@bmuschko](https://discuss.gradle.org/u/bmuschko)
#### Post date: [November 12, 2015, 4:09pm UTC](https://discuss.gradle.org/t/testing-a-settings-plugin/12716/6 "2015-11-12T16:09:54Z")

</div>

This functionality was already working with Gradle 2.6. You don’t have to use Gradle 2.9-RC for that. I don’t think @Boaz_Jan was necessarily asking for cross-version testing functionality here.

---

<div class="post-metadata">

### Author: ![Boaz\_Jan](https://avatars.discourse-cdn.com/v4/letter/b/df705f/32.png) [@Boaz\_Jan](https://discuss.gradle.org/u/Boaz_Jan)
#### Post date: [November 12, 2015, 9:43pm UTC](https://discuss.gradle.org/t/testing-a-settings-plugin/12716/7 "2015-11-12T21:43:09Z")

</div>

Thanks @bmuschko!

The missing code part was  
`settingsFile << """ buildscript { dependencies { classpath files($pluginClasspath) } } """`  
plus some manipulation on the pluginClasspath.

I think it’s worth to mention in the documentation that the withPluginClasspath of the GradleRunner does not effect the settings evaluation and needs to be defined manually…

Thanks!

---

<div class="post-metadata">

### Author: ![Boaz\_Jan](https://avatars.discourse-cdn.com/v4/letter/b/df705f/32.png) [@Boaz\_Jan](https://discuss.gradle.org/u/Boaz_Jan)
#### Post date: [November 12, 2015, 10:35pm UTC](https://discuss.gradle.org/t/testing-a-settings-plugin/12716/8 "2015-11-12T22:35:52Z")

</div>

Also, withProjectDir does not effect settings evaluation, I’m accessing a file within the Settings plugin and passing a relative path to the settings.gradle location does not work. absolute path does.

---

<div class="post-metadata">

### Author: ![bmuschko](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/bmuschko/32/5458_2.png) [@bmuschko](https://discuss.gradle.org/u/bmuschko)
#### Post date: [November 13, 2015, 3:03am UTC](https://discuss.gradle.org/t/testing-a-settings-plugin/12716/9 "2015-11-13T03:03:21Z")

</div>

Can you provide some sample code? At the moment I don’t fully understand your problem.

---

<div class="post-metadata">

### Author: ![Boaz\_Jan](https://avatars.discourse-cdn.com/v4/letter/b/df705f/32.png) [@Boaz\_Jan](https://discuss.gradle.org/u/Boaz_Jan)
#### Post date: [November 15, 2015, 11:46am UTC](https://discuss.gradle.org/t/testing-a-settings-plugin/12716/10 "2015-11-15T11:46:14Z")

</div>

> **[boazj/gradle-testkit-project-dir-issue](https://github.com/boazj/gradle-testkit-project-dir-issue)**
>
> Contribute to gradle-testkit-project-dir-issue development by creating an account on GitHub.

The issue is simple, GradleRunner has 2 methods that don’t take effect on Settings:

- withProjectDir
- withPluginClasspath

withProjectDir should set the current working dir thus allowing us to use relative paths. My test shows that this does not apply to relative paths used from a settings plugin.

withPluginClasspath should set the injected plugin classpath, but it does not set it for the settings as seen by your example.

---

<div class="post-metadata">

### Author: ![bmuschko](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/bmuschko/32/5458_2.png) [@bmuschko](https://discuss.gradle.org/u/bmuschko)
#### Post date: [November 15, 2015, 12:59pm UTC](https://discuss.gradle.org/t/testing-a-settings-plugin/12716/11 "2015-11-15T12:59:21Z")

</div>

Your logic in the `Settings` plugin should determine the path based on [Settings.getSettingsDir()](https://docs.gradle.org/current/dsl/org.gradle.api.initialization.Settings.html#org.gradle.api.initialization.Settings:settingsDir) to ensure the proper directory. If you don’t, the path used for executing your build is used which is not the path the project you create in the tmp directory. You’d run into the same issue if you’d execute a build that uses your plugin from a different directory than the one that hosts your `settings.gradle`.

```
import org.gradle.api.Plugin
import org.gradle.api.initialization.Settings

class SettingsPlugin implements Plugin<Settings> {
    @Override
    void apply(Settings settings) {
        println new File(settings.settingsDir, 'test.test').text
    }
}
```
