Migration of integration test task to 4.0-milestone-2


(Robert) #1

I am migrating a Java library to Gradle 4.0-milestone2 and I encountered some issues with the integration task defined below.

This task allows me to have two different source directories src/test and src/integration and have separate gradle tasks to run them, ./gradlew test and ./gradlew integration.

Contents of integration.gradle

sourceSets {
  integration {
    java {
      compileClasspath += main.output + test.output
      runtimeClasspath += main.output + test.output
      srcDir file('src/integration/java')
    }
    resources.srcDir file('src/integration/resources')
  }
}
configurations {
  integrationCompile.extendsFrom testCompile
  integrationRuntime.extendsFrom testRuntime
}
idea {
  module {
    testSourceDirs += file('src/integration/java')
    scopes.TEST.plus += [configurations.integrationCompile]
  }
}
task integration(type: Test) {
  testClassesDir = sourceSets.integration.output.classesDir
  classpath = sourceSets.integration.runtimeClasspath
}

integration.mustRunAfter test

Contents of build.gradle

apply plugin: 'java-library'
apply plugin: 'idea'

apply from: './integration.gradle'

targetCompatibility = '1.7'
sourceCompatibility = '1.7'

dependencies {

  api 'com.github.ihsanbal:LoggingInterceptor:2.0.0'
  api 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0'
  api 'com.squareup.retrofit2:retrofit:2.0.2'
  api 'com.squareup.retrofit2:converter-gson:2.0.2'
  api 'com.squareup.retrofit2:adapter-rxjava:2.0.2'

  testImplementation 'junit:junit:4.12'
}

test {
  testLogging.showStandardStreams = true
}


task copyTestResources(type: Copy) {
  from sourceSets.test.resources
  into sourceSets.test.output.classesDir
}
processTestResources.dependsOn copyTestResources

There are two problems with this configuration.

  1. copyTestResources task does not work as classesDir is deprecated and classesDirs is not compatible.

  2. The classpaths are not including the library dependencies.
    Compilation fails full of the following errors

    error: cannot find symbol
    error: package SOMETHING does not exist

What would be the equivalent on 4.0-m2 ?
Thanks for your help :slight_smile:


(Stefan Oehme) #2

You’re missing integrationImplementation.extendsFrom(testImplementation) and integrationRuntimeOnly.extendsFrom(testRuntimeOnly). Btw if you are not going to use the old compile/runtime anymore, then you can skip those two extends relationships instead.


(Stefan Oehme) #3

You shouldn’t be doing that. The classes dir is for classes, not resources.

Instead you should have integration.runtimeClasspath += integration.output


(Robert) #4

@st_oehme thanks for the tips.
The following indeed worked from the command line:

build.gradle

apply plugin: 'java-library'
apply plugin: 'idea'

apply from: './integration.gradle'

targetCompatibility = '1.7'
sourceCompatibility = '1.7'

dependencies {

  api 'com.github.ihsanbal:LoggingInterceptor:2.0.0'
  api 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0'
  api 'com.squareup.retrofit2:retrofit:2.0.2'
  api 'com.squareup.retrofit2:converter-gson:2.0.2'
  api 'com.squareup.retrofit2:adapter-rxjava:2.0.2'

  testImplementation 'junit:junit:4.12'
}

test {
  testLogging.showStandardStreams = true
}

integration.gradle

sourceSets {
  integration {
    java {
      compileClasspath += main.output + test.output
      runtimeClasspath += main.output + test.output
      srcDir file('src/integration/java')

      integration.runtimeClasspath += integration.output
    }
    resources.srcDir file('src/integration/resources')
  }
}
configurations {
  integrationImplementation.extendsFrom testImplementation
  integrationRuntimeOnly.extendsFrom testRuntimeOnly
}
idea {
  module {
    testSourceDirs += file('src/integration/java')
    scopes.TEST.plus += [configurations.integrationImplementation]
  }
}
task integration(type: Test) {
  testClassesDirs += sourceSets.integration.output.classesDirs
  classpath = sourceSets.integration.runtimeClasspath
}
integration.mustRunAfter test

However there’s an issue when syncing AndroidStudio/Intellij related to the integrationImplementation clause

Error: Resolving configuration 'integrationImplementation' directly is not allowed

Any idea on this one?
Thanks again


(Stefan Oehme) #5

That’s the culprit. Resolving the implementation configuration directly is meaningless, as its dependencies are used in different contexts and thus Gradle could not decide how to resolve it (for compile usage or for runtime usage). Instead add integrationRuntimeClasspath and integrationCompileClasspath to the IDE classpath.


(Robert) #6

@st_oehme nailed it one more time :slight_smile:

The following line did the trick.

scopes.TEST.plus += [configurations.integrationRuntimeClasspath, configurations.integrationCompileClasspath]

A little bit outside the original topic but still related, would anyone know why with this integration test configuration, Intellij/AndroidStudio is not able to detect Tests when running it from inside the IDE ?

It executes, but fails with the error Empty test suite.

Thanks again!