# Setting up test system properties via plugin or root script?

**URL:** <https://discuss.gradle.org/t/setting-up-test-system-properties-via-plugin-or-root-script/48731>\
**Category:** Help/Discuss\
**Created:** [June 19, 2024, 10:23am UTC](https://discuss.gradle.org/t/setting-up-test-system-properties-via-plugin-or-root-script/48731 "2024-06-19T10:23:36Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Talavera316](https://avatars.discourse-cdn.com/v4/letter/t/ecd19e/32.png) [@Talavera316](https://discuss.gradle.org/u/Talavera316)\
**Post date:** [June 19, 2024, 10:23am UTC](https://discuss.gradle.org/t/setting-up-test-system-properties-via-plugin-or-root-script/48731/1 "2024-06-19T10:23:36Z")

</div>

The root project consists of dozen subprojects.  
For some of them I need to set up a test property, like

```gradle
test {
    systemProperty 'propKey', propValue // propValue is evaluated during the build
}

```

Looks like there are 2 basic ways to propagate the property among the given set of subprojects.

1. via buildSrc precompiled convention script plugin, which will be applied to the subprojects
2. via _subprojects_ “loop” in the root script

Which way is more elegant, conventional, readable, maintainable and clasic? 🙂

---

<div class="post-metadata">

**Author:** ![Vampire](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/vampire/32/9082_2.png) [@Vampire](https://discuss.gradle.org/u/Vampire)\
**Post date:** [June 19, 2024, 11:18am UTC](https://discuss.gradle.org/t/setting-up-test-system-properties-via-plugin-or-root-script/48731/2 "2024-06-19T11:18:03Z")

</div>

Using `subprojects { ... }`, `allprojects { ... }`, `project("...") { ... }`, or any other means to do cross-project configuration is bad practice and should be avoided.  
It immediately adds project coupling and disturbs or disables some more sophisticated Gradle features or optimizations.

So your option 1 it is. Convention plugins in `buildSrc` or an included build, for example implemented as precompiled script plugins, that you apply to the projects where you want their effect to be present directly.

---

<div class="post-metadata">

**Author:** ![Talavera316](https://avatars.discourse-cdn.com/v4/letter/t/ecd19e/32.png) [@Talavera316](https://discuss.gradle.org/u/Talavera316)\
**Post date:** [June 19, 2024, 4:33pm UTC](https://discuss.gradle.org/t/setting-up-test-system-properties-via-plugin-or-root-script/48731/3 "2024-06-19T16:33:08Z")

</div>

Björn,  
type of your opinion is ’ Roma locuta, causa finita’ - I have delegated the propagation of the property to the convention plugin. However the value of the property I left evaluated in the root script and redeclared there in the ext var block.  
What convinces me is the “sophisticated Gradle features or optimizations” capabilities.  
thanks a lot.  
T.

PS.  
For custom test tasks like: task customTestTask(type: Test)

do I need to set up the property from the test prop map to custom prop map in that way:  
systemProperty ‘propKey’, test.getSystemProperties().get(‘propKey’)

or there is some implicit way to get it set.

---

<div class="post-metadata">

**Author:** ![Vampire](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/vampire/32/9082_2.png) [@Vampire](https://discuss.gradle.org/u/Vampire)\
**Post date:** [June 20, 2024, 3:19pm UTC](https://discuss.gradle.org/t/setting-up-test-system-properties-via-plugin-or-root-script/48731/4 "2024-06-20T15:19:45Z")

</div>

> type of your opinion is

That’s not an opinion, but a fact.  
Cross-project configuration is evil and should be avoided whereever possible.  
That’s how it is and what also the Gradle folks say, for example in the userguide at [Sharing Build Logic between Subprojects](https://docs.gradle.org/current/userguide/sharing_build_logic_between_subprojects.html#sec:convention_plugins_vs_cross_configuration).

> redeclared there in the ext var block.

Practically any usage of `ext` or `extra` properties is also bad practice and just a work-around for doing something not the “right” way. 😉

> or there is some implicit way to get it set.

If you want to set a system property on all tasks of type `Test`, you can do so using for example `tasks.withType(Test).configureEach { ... }`. (don’t leave out the `configureEach` even if it works or it breaks task-configuration avoidance for all tasks of type `Test`)

There is no automatic inheriting from anything from default test tasks to custom test tasks, as that might as well be not wanted, Gradle simply cannot know.

---

<div class="post-metadata">

**Author:** ![Talavera316](https://avatars.discourse-cdn.com/v4/letter/t/ecd19e/32.png) [@Talavera316](https://discuss.gradle.org/u/Talavera316)\
**Post date:** [June 21, 2024, 10:03am UTC](https://discuss.gradle.org/t/setting-up-test-system-properties-via-plugin-or-root-script/48731/5 "2024-06-21T10:03:43Z")

</div>

> [@Vampire](#):
>
> Practically any usage of `ext` or `extra` properties is also bad practice and just a work-around for doing something not the “right” way. 😉

Maybe in the nice world where you move your perfect Maven project (build of pretty independent subprojects) to Gradle this advice is easy to follow, but e.g. when you must migrate old Ant project with its legacy drawbacks you must use some “work-arounds”.

The question is what work-around mechanism to use not to get into bigger troubles.

Let’s say (like above) you must provide some common properties for subprojects’ tests.  
As you said: the fact is that the best way to provide them is to use buildSrc convention plugin. So far so good.

But where the properties should be “born”?  
For many reason the convention plugin seem to be not the right place for it:  
a) the plugin would repeat I/O operation to read/load the properties data while in the root script you just read them once  
b) the plugin is not capable to evaluate the properties as it just has not enough context. Providing the plugin with broader context would be just ugly solution.

So the root script seems to be the best place to evaluate the properties.

But the final question is how to pass them from the root to the plugin, in a safe way, ‘not disabling sophisticated Gradle features or optimizations’.

Is there a better way than Extras?

---

<div class="post-metadata">

**Author:** ![Vampire](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/vampire/32/9082_2.png) [@Vampire](https://discuss.gradle.org/u/Vampire)\
**Post date:** [June 21, 2024, 4:30pm UTC](https://discuss.gradle.org/t/setting-up-test-system-properties-via-plugin-or-root-script/48731/6 "2024-06-21T16:30:16Z")

</div>

> when you must migrate old Ant project with its legacy drawbacks you must use some “work-arounds”.

There’s usually always a way to do it differently. 😃  
But as long as you are aware those are unclean work-arounds and it works for you, great. 🙂

> Let’s say (like above) you must provide some common properties for subprojects’ tests.

Depends on the gory details.  
If they are for example static values, put them to gradle.properties in the root project.  
If you need to do some calculations, maybe a shared build service would be an appropriate way, as it is build-run-scoped, so the calculation would only be done once and can be used by multiple projects safely.

Depending on extra properties in the root project should latest be a problem when isolated projects become production-ready.
