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

Reply via email to