Quantcast
Channel: Gradle Forums - Latest posts
Viewing all articles
Browse latest Browse all 19859

How to share tests between multiple projects?

$
0
0

Greetings,

We’re struggling to setup a project where two subprojects must share a set of classes, and related test classes.

Detailed problem:

The root project R contains 3 java subprojects A, B, C. Both projects A and B are applications which depend on C. And C contains common code (but there is no dependency between A and B).
A lot of test classes target code defined in C, but they can yield different results wether they are run from A or from B. We don’t want to copy theses test classes into A or B, since they are common (and target classes in C). We want a single test codebase for them.
And we want to be able to launch a single test class (or test package) from within Eclipse, either from project A or project B.

Our imperfect solution:

The setup we use at the moment can be changed, it works with gradle eclipse plugin, but not with buildship (see below). Also note that it has been built before Eclipse allowed test code separation, so we could do some improvements on this topic.
Here is what we do at the moment:

We created a 4th subproject T, which contains only these common test classes. and we put the test classes in “src/main/java”.
In projects A and B, we define a test dependency to this project T, and we add the output folder to the tests. Example for project A:
project(":A").test.testClassesDirs += project(":T").sourceSets.main.output
This work perfectly fine with pure gradle builds:
gradlew :A:build

But then, how do we launch a single test class from Eclipse using either gradle or JUnit ? We cannot right-click a test class in project T, and “run as -> gradle test” or “run as -> junit test”. Even if these classes were in the test classes of project C (in “src/test/java”), Eclipse cannot tell if we want to run them from A or from B (running them from C itself won’t work because we need to load some implementation classes from A or from B to make things work).
The trick we use is to add some Eclipse specifics. Example for project A:

def commonTestsDir = /* path to src/main/java of project T */
eclipse {
    project {
        linkedResource name: 'common-tests', type: '2', location: commonTestsDir
    }
    classpath.file.withXml {
        def node = it.asNode()
        node.appendNode('classpathentry', [kind: 'src', path: 'common-tests', exported: true])
    }
}

Doing this on both A and B, then running “gradle eclipse” will happily show a folder link “common-tests” under each projects (A and B) where we can browse for test classes, and run them from right-clicks, while allowing Eclipse to know if we’re in A or B.

Note that we simultaneously have a project dependency to T, explicitely added so that “gradlew test” works fine AND a classpath dependency added to Eclipse buildpath with our customization added to gradle eclipse plugin. This works like a charm up to this stage.

Our issue with buildship:

But this doesn’t work with buildship. If we “Refresh gradle project”, we still have the project dependency, but the Eclipse classpath dependency, but the Eclipse classpath dependency gets lost.
We also tried to use “minusConfiguration” to remove the project dependency on the Eclipse classpath (so that the classpath dependency could be taken into account again), but this had no effect.
As a result, we can list our “common-tests” files from A or B, but since they’re not in the Eclipse classpath, we cannot right-click them to launch tests.

We did setup this originally with gradle 4.1 and buildship 2.1.2, and we now moved to gradle 6.3 and we tried with buildship 2.1.2 and buildship 3.1.4.

Everything can probably be done without project T, by moving the test classes to project C in “src/test/java”. But if I’m not mistaken, I don’t think that will solve any issue.

Any hints would be really appreciated. Thanks in advance.


Viewing all articles
Browse latest Browse all 19859

Trending Articles