Trouble setting testClassesDir via parent project

I have a large multi-project build, and I’m trying to add a new set of sub-projects for an integration test suite. I want to have these integration tests run as part of the build, but also be able to package the whole test suite up so that it can be run against a fully deployed application. My projects form a tree something like this:


  • many sub-projects which make up application
  • it: parent project for integration tests
    – base: common classes used by most integration test suites
    – smoke: very basic set of tests
    eventually many more integration test suites

In the smoke project, my test code is in the src/main/groovy directory. In the it/build.gradle I have the following, which creates the integrationTest task for each of the sub-projects other than base:

subprojects {
  apply plugin: 'groovy'

  if ( != 'base') {
    task integrationTest(type: Test, dependsOn: 'classes') {
      testSrcDirs = sourceSets.main.allSource.srcDirs as List
      testClassesDir = sourceSets.main.output.classesDir

The key point here is that the test task is created by the sub-project, and should run all of the test classes compiled from the main sources.

When I run the integrationTest task, my tests are not run, and and the task is listed as up-to-date. Using the -info flag, I see the follwoing:

:it:smoke:integrationTest (Thread[Task worker Thread 5,5,main]) started.
file or directory '/home/wesley/work/projects/dm3/dev-branches/v4/it/smoke/build/classes/test', not found
Skipping task ':it:smoke:integrationTest' as it has no source files.
:it:smoke:integrationTest UP-TO-DATE
:it:smoke:integrationTest (Thread[Task worker Thread 5,5,main]) completed. Took 0.0 secs.

This suggests to me that the testClassesDir property is not correctly being set to the main output directory, but is remaining at the default setting of the test output directory. To ensure that the task is correctly being applied to the child project, I added a task to it/smoke/build.gradle:

task describeIntegrationTest << {
  getTasksByName('integrationTest', false).each {
    println "--- $it ---"
    println "testClassesDir: $it.testClassesDir"

Running this task produces the following:

--- task ':it:smoke:integrationTest' ---
testSrcDirs: [/home/wesley/work/projects/dm3/dev-branches/v4/it/smoke/src/main/resources, /home/wesley/work/projects/dm3/dev-branches/v4/it/smoke/src/main/java, /home/wesley/work/projects/dm3/dev-branches/v4/it/smoke/src/main/groovy]
testClassesDir: /home/wesley/work/projects/dm3/dev-branches/v4/it/smoke/build/classes/main

Clearly showing that the testClassesDir has correctly been applied to the integrationTest task.

If I move the definition of this task from it/build.gradle to it/smoke/build.gradle, the tests get executed as expected. This is not a pleasant solution though, since I will have many sub-projects of integration tests.

Have I missed something here, why would the integrationTest task show the main classes directory when inspected by the describeIntegrationTest task, but use the test classes directory when it executes?

I’m not sure what changed, but I tried moving the task definition back to the integration test parent project, and everything worked. It must have all been a bad dream.