lundi 14 novembre 2016

Feedback on gradle configuration for `test-support` code

I have been thinking about this a lot lately and wanted to get some feedback on the idea I had a couple of days ago.

Problem:

In a typical code base, every module has a main and a test source-set. This can work quite well for some time but sooner or later I always stumble upon the situation where I would like to group together a bunch of classes which allow easier testing of code that involves a certain module. A good example would be a set of hamcrest matcher classes for a given module.

  • Assumption 1:
    As hamcrest is a library for test-code, these matchers should not go into the main source-set.

  • Assumption 2: These classes should also not go into the test source-set either, as the dependency on the test source is just a workaround for these classes to be available. One usually does not want a dependency on the actual tests. It is also not recommended (by Netflix) to define a dependency on the test source-set of a project.

Solution 1:

Create a dedicated module that contains these classes in the main source-set and simply define a test-dependency on this module wherever you need them.

This was the approach I went with for quite some time now but I don't really like it.

  • First, I never came up with a nice name, except appending testSupport to the name of the original module which results in names like core-testSupport, persistence-testSupport and so on.

  • Second, it creates a lot of modules and the project-tree gets kind of polluted with these modules.

Solution 2: (The one I would appreciate feedback on)

configurations {
    testSupportCompile.extendsFrom compile
    testSupportRuntime.extendsFrom runtime
}

sourceSets {
    testSupport {
        compileClasspath += sourceSets.main.output + configurations.testSupportCompile
        runtimeClasspath += compileClasspath + configurations.testSupportRuntime
    }
}

task testSupportJar(type: Jar) {
    from sourceSets.testSupport.output
    classifier 'testSupport'
}

artifacts {
    testSupportCompile testSupportJar
}

The above gradle configuration could go in file named testSupport.gradle and be applied to any module that needs this dedicated source-set for providing classes that could be reused in tests.

Defining a dependency would work like this:

testCompile project(path: ':core', configuration: 'testSupportCompile')

I am still kind of new to gradle and researched a lot but I still have a few questions.

  1. I understand that declaring a new source-set automatically creates two configurations: <sourceSet>Compile and <sourceSet>Runtime. What I don't really like about this approach is, that one has to use the testSupportCompile configuration when declaring the dependency. Is there a way to alias this to only testSupport or something like that?

  2. My project compiles fine at the moment. However, I am not sure if I am doing things the right way. How could this configuration be improved?

  3. Are there any other ways of achieving the desired functionality? While researching, I did not really find much on this topic which makes me feel like that I am either using the wrong search terms or doing something stupid that simply should not be done.

I know that this is kind of a broad question but I am not sure on where to get proper feedback on stuff like that except here.

Aucun commentaire:

Enregistrer un commentaire