Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle custom test sourceSet

I have a gradle project and have main and test as sourceSets.

I do want test-main not to be part of test source sets. Now the issue I encounter is that when projects are build, the test-main is marked as Sources Root instead of Test Sources Root.

This leads to compilation errors and I have to manually mark test-mains as Source Test Root for all subprojects.

I created a task in order to enforce intellij to mark them as Sources Test Root but seems like I am doing something wrong.

hints:

  • Intellij IDEA 2016.2
  • Gradle 2.14

Thanks,

subprojects {
  apply plugin: 'java' // all our projects are Java projects

  sourceCompatibility = '1.8'
  targetCompatibility = '1.8'

  tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
    options.warnings = false // There are too many :-(
  }

  configurations {
    testMainsCompile.extendsFrom testCompile
    testMainsRuntime.extendsFrom testMainsCompile
  }

  sourceSets {
    main {
      java {
        srcDirs = ['src']
      }
      resources {
        srcDirs = ['src']
      }
    }
    test {
      java {
        srcDirs = ['test']
      }
      resources {
        srcDirs = ['test']
      }
    }
    testMains {
      java {
        srcDirs = ['test-mains']
        compileClasspath = test.output + main.output + configurations.testMainsCompile
        runtimeClasspath = output + compileClasspath + configurations.testMainsRuntime
      }
      resources {
        srcDirs = ['test-mains']
      }
    }
  }

  // dummy task just to convince intellij idea that testMains is a test class folder
  task testMainsTest(type: Test) {
    testClassesDir = sourceSets.testMains.output.classesDir
    classpath += sourceSets.testMains.runtimeClasspath
  }

[...]

}
like image 908
Maxime Avatar asked Jul 14 '16 08:07

Maxime


People also ask

What is Sourceset in Gradle?

An AndroidSourceSet represents a logical group of Java, aidl and RenderScript sources as well as Android and non-Android (Java-style) resources.

Why is Gradle skipping tests?

In this case, we might skip the tests temporarily to reduce the overhead of compiling and running them. Undoubtedly, ignoring the tests can cause many serious issues. In this short tutorial, we'll learn how to skip tests when using the Gradle build tool.

What is runtimeClasspath in Gradle?

main. runtimeClasspath' contains the compiled classes of the source set, and task autowiring automatically adds the necessary task dependencies. Maybe you want 'sourceSets. main. compileClasspath'.


2 Answers

I'm really late to the party but with 11k views this might be useful to someone else. At this point we are up to Gradle 6 and IntelliJ 2020. To link parallel test folders to Gradle and IntelliJ you need to create the folder structure, then declare the source-set almost exactly as above. The source sets tell IntelliJ about the sub-modules so they appear in IntelliJ as folders with blue squares.

Maxime answered his on question about making the source folders test source, that is handled by the idea plugin (although you might be able to do it manually in IntelliJ too from the context-menu on the folder).

BUT, he there are a couple of things not mentioned here.

I probably would keep the resource source NEXT to the Java source folder, not the same as it. Normally a Gradle/Maven application has "resources" next to "java".

A word of warning about folder names. Maxime has different source-set names and folder names. I tried that, I wanted the - in the folder name. But IntelliJ went a bit off the rails in the project structure when I tried it, showing a red-colored content source for the source-set name. It could just be me, maybe I had something else wrong :)

Maxime cleverly extended testCompile to get the project compileClasspath and then used the same value for the runtimeClasspath. But what if the runtimeClasspath was different at the project level? The gradle snippit I use gets them directly from the project (main and test are the default sub-modules in the project):

    testIntegration {
    java {
        compileClasspath += project.configurations.testCompileClasspath + main.output + test.output
        runtimeClasspath += project.configurations.testRuntimeClasspath + main.output + test.output
        srcDir file('src/testIntegration/java')
    }
    resources {
        srcDir file('src/testIntegration/resources')
    }
}
like image 122
Joel Mussman Avatar answered Oct 31 '22 04:10

Joel Mussman


I had to specify for idea plugin this:

subprojects {
  apply plugin: 'idea'

  idea {
    module {
      testSourceDirs += file('test-mains')
    }
  }
}
like image 24
Maxime Avatar answered Oct 31 '22 03:10

Maxime