7

I'm trying to make sure my test-jar published from maven has the right transitive dependencies.

The test-jar doesn't, for instance, generate with a dependency on the non-test-jar.

Similarly, say AAA publishes a test-jar, and BBB contains a test-scoped dependency for AAA's test-jar. In CCC's tests, when I use a class from BBB's test-jar that uses a class from AAA's test-jar, I get a 'class not found' error on the class from AAA's test-jar - i.e., BBB's tests' transitive dependencies aren't properly recorded at all.

Is there any way to make depending on BBB's test jar properly pull in transitive dependencies?

I have example code for all this in https://github.com/nkronenfeld/transitive-test-dependencies

There are two commented-out dependencies in CCC/pom.xml for the BBB's normal jar, and AAA's test-jar, neither of which seem like they should be needed. CCC's test goal won't however, run without either.

Nathan Kronenfeld
  • 473
  • 1
  • 5
  • 14
  • 4
    short answer test scoped dependencies don't have transitive dependencies see: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html Apart from that I've got the feeling having transitive dependencies through tests sounds like a smell.... – khmarbaise Feb 11 '18 at 21:00
  • I guess you can at least vote for this (old) issue : https://issues.apache.org/jira/browse/MNG-1378 – Donatello Sep 24 '18 at 15:48
  • @khmarbaise we have local test lib i would like to include transitively due to some exclusions (enforcer confilcts) not to be duplicated (and no, i can't inject them into depsManagement section). – Simon Logic Nov 06 '21 at 13:09

2 Answers2

4

As khmarbaise said: Test dependencies are not transitive. If A declares a test dependency on B, this means that A needs B to run its tests. Users of A do not need to know about this. If a test-jar needs something to run, it should declare a compile dependency on this.

J Fabian Meier
  • 33,516
  • 10
  • 64
  • 142
  • The user of A's tests has a test dependency on those tests. A's test itself should have compile dependencies on everything that it needs to run. – J Fabian Meier Feb 13 '18 at 08:10
  • 1
    I don't understand what you're getting at - that is true, but seems to me to be to my point that the dependency should be transitive – Nathan Kronenfeld Feb 14 '18 at 15:45
  • compile dependencies are transitive, test dependencies are not. – J Fabian Meier Feb 15 '18 at 10:00
  • well, the subject of this question is that test dependencies should be transitive (in test scope), as explained by the use case... so we are looking for a workaround ! – Donatello Sep 24 '18 at 15:41
  • @Donatello: I would object. I offered a solution for the use case. – J Fabian Meier Sep 24 '18 at 17:21
  • @JFMeier your solution seems to impact the **compile** scope of the project, to address an issue related to tests, so I think this is not fully compliant. Workarounds are: duplicating B's tests dependencies in A's dependencies as **test** scope (difficult to maintain), or, defining B's tests dependencies as **compile** scope (which is worst). The question is: is there a plugin allowing to add transitive dependencies for test-jars, when built from the same project as the main jar ? – Donatello Sep 26 '18 at 11:01
  • I think there is a misunderstanding of what a test dependency is. Test dependencies are only relevant during the build of the artifact itself. So test dependencies of B are only relevant for _building_ B, not when you use B. If B is a test jar, it should have compile dependencies on C,D,E, and if A declares a test dependency on B, it gets C,D,E as well. I do not see problems in this approach. Do you? – J Fabian Meier Sep 26 '18 at 11:32
  • I think you did not get the issue, where A tests uses B test-jar which use C as test dependency, then A needs C to run tests. That's why we need transitive dependencies. But then, how to declare C as compile dependency for B test-jar, without having C as compile dependency in B jar ? You're solution does not elaborate this point, where I think the only way is to have different projects for B and B-tests. – Donatello Oct 04 '18 at 08:34
  • But, does a plugin can do that properly ? It seems maven-jar-plugin obviously advise to use separate projects : https://maven.apache.org/plugins/maven-jar-plugin/examples/create-test-jar.html#The_preferred_way – Donatello Oct 04 '18 at 08:37
  • 1
    @Donatello Oh, now I see. You were talking about test-jars that are automatically generated from the test classes of the project. I would avoid to build these, at least if you have hierarchies of these. Separate test projects are better to handle (they were the thing I was talking about all the time, sorry I missed your point). – J Fabian Meier Oct 04 '18 at 10:04
1

I ran into this same issue. In my case, I had stub classes in project A, stub classes in project B which depended on A's stub classes, and then I wanted to use B's stub classes in project C.

I think the "right" way to attack this problem is to create two additional projects: A-stubs and B-stubs:

  • B-stubs directly depends on A-stubs (compile scope).
  • A includes A-stubs in its test scope.
  • B includes B-stubs in its test scope.
  • C also includes B-stubs in its test scope.

With that in place, the transitive dependencies of B-stubs should be handled just fine. You shouldn't need to build any test JARs at all.

Brandon
  • 2,367
  • 26
  • 32