On 17/10/2010, at 10:50 PM, Dierk König wrote:
> Here is a small design question:
> why do we need a special handling for testing
> in the source sets, tasks, configurations, etc?
A very interesting question.
Beyond the Test task class itself, there's actually very little special
handling for testing in the implementation of Gradle. Almost all the support
comes from the generic source set concept. The only real special handling is in
the java plugin, which adds a 'test' source set, which has a dependency on the
'main' source set.
>
> Having played a little with multi-project setup,
> it seems to me that a separate test project
> that depends on the main project would
> just as well do the job without introducing
> any special handling.
>
> IDEs would map this as dependent modules
> and would thus provide the same support as
> today.
>
> Some tasks may become easier like excluding
> test code from coverage, checkstyle,
> and documentation.
Introducing the concept of test code also makes this stuff easier for the
majority of projects, because we can make use of certain conventions about what
test code means. That is, you generally don't want to report on the coverage of
your test code, or to include it in the API documentation, or publish a jar for
it, and so on.
But on the other hand, using a separate project for test code might help
highlight that all code is equally important for delivery, whether it is test
or production code.
Personally, I think that test code is an important concept for a build tool to
model. People do distinguish between the test and production code in how they
talk about the code, what they expect the code will do, how it will participate
in the build. It would be a shame not to model that reality.
However, there are some awkward aspects to how we model things now, which
suggest things might be done better.
One example is that there are two distinct task namespaces. The first part of a
task's fully qualified path is a hierarchical project path. The second part is
a munging of the source set name and task name. So you have task paths like
:core:compileTestJava. Whereas, it might be better to have a task path like
:core:test:java:compile.
Another example is that it is difficult to apply behaviour to certain source
sets and not others. One solution to this which we've discussed is to be able
to apply plugins to source sets. So you could do this kind of thing:
sourceSets {
main {
apply plugin: 'antlr' // use Antlr only for production code
}
test {
apply plugin: 'groovy' // use Groovy only for testing
}
functionalTest {
apply plugin: 'functional-test'
}
}
if, instead, the main, test and functionalTest source sets where separate
projects, this would work more naturally.
Another awkwardness is when you want to model things such as a project which
has only tests. You apply the 'java-base' plugin and then add in a 'test'
source set and a 'test' task. If, instead the tests were in a separate project,
we could have a 'test' plugin which you could apply, and there's be no need to
use the *-base plugins.
Perhaps an improvement to our model would be to treat source sets as a kind of
project. Or flip it around, so that what is currently a project is simply a
composite source set. Or both.
The result would be that each logical project would contain a 'main' subproject
and a 'test' subproject. Each of the 'main' and 'test' projects would have
their own 'classes', 'compileJava' and 'clean' tasks and so on. And their own
'compile' and 'runtime' configurations. And their own build directories. And
their own jar publications. And their own build files.
The logical project would simply be an aggregate project. It would inject
configuration into the child projects. Or not - they might have their build
files.
One thing to note is that this structure would be by convention only. You'd be
able to combine the various types of projects into whatever structure you'd
like.
It's a very interesting question, indeed.
--
Adam Murdoch
Gradle Developer
http://www.gradle.org
CTO, Gradle Inc. - Gradle Training, Support, Consulting
http://www.gradle.biz