I have been thinking about this a lot lately and wanted to get some feedback on the idea I had a couple of days ago.
Problem:
In a typical code base, every module has a main
and a test
source-set. This can work quite well for some time but sooner or later I always stumble upon the situation where I would like to group together a bunch of classes which allow easier testing of code that involves a certain module. A good example would be a set of hamcrest
matcher classes for a given module.
Assumption 1:
Ashamcrest
is a library for test-code, these matchers should not go into themain
source-set.Assumption 2: These classes should also not go into the
test
source-set either, as the dependency on thetest
source is just a workaround for these classes to be available. One usually does not want a dependency on the actual tests. It is also not recommended (by Netflix) to define a dependency on thetest
source-set of a project.
Solution 1:
Create a dedicated module that contains these classes in the main
source-set and simply define a test-dependency on this module wherever you need them.
This was the approach I went with for quite some time now but I don't really like it.
First, I never came up with a nice name, except appending
testSupport
to the name of the original module which results in names likecore-testSupport
,persistence-testSupport
and so on.Second, it creates a lot of modules and the project-tree gets kind of polluted with these modules.
Solution 2: (The one I would appreciate feedback on)
configurations {
testSupportCompile.extendsFrom compile
testSupportRuntime.extendsFrom runtime
}
sourceSets {
testSupport {
compileClasspath += sourceSets.main.output + configurations.testSupportCompile
runtimeClasspath += compileClasspath + configurations.testSupportRuntime
}
}
task testSupportJar(type: Jar) {
from sourceSets.testSupport.output
classifier 'testSupport'
}
artifacts {
testSupportCompile testSupportJar
}
The above gradle configuration could go in file named testSupport.gradle
and be applied to any module that needs this dedicated source-set for providing classes that could be reused in tests.
Defining a dependency would work like this:
testCompile project(path: ':core', configuration: 'testSupportCompile')
I am still kind of new to gradle and researched a lot but I still have a few questions.
I understand that declaring a new source-set automatically creates two configurations:
<sourceSet>Compile
and<sourceSet>Runtime
. What I don't really like about this approach is, that one has to use the testSupportCompile configuration when declaring the dependency. Is there a way to alias this to onlytestSupport
or something like that?My project compiles fine at the moment. However, I am not sure if I am doing things the right way. How could this configuration be improved?
Are there any other ways of achieving the desired functionality? While researching, I did not really find much on this topic which makes me feel like that I am either using the wrong search terms or doing something stupid that simply should not be done.
I know that this is kind of a broad question but I am not sure on where to get proper feedback on stuff like that except here.