Uploaded image for project: 'Maven'
  1. Maven
  2. MNG-1378

Make dependencies of test-jars transitive

Details

    Description

      test-jar transitive dependencies are calculated as per compile scope rather than test scope.

      The situation is demonstrated nicely in it0077:

      • module sub1 has a test-scoped dependency of commons-lang
      • module sub2 has a test-scoped dependency of sub1 test-jar

      sub2 tests should inherit the commons-lang transitive dependency. For example:

      Index: maven-core-it/it0077/sub2/src/test/java/org/apache/maven/it0077/PersonTwoTest.java
      ===================================================================
      — maven-core-it/it0077/sub2/src/test/java/org/apache/maven/it0077/PersonTwoTest.java (revision
      328307)
      +++ maven-core-it/it0077/sub2/src/test/java/org/apache/maven/it0077/PersonTwoTest.java (working
      copy)
      @@ -1,6 +1,7 @@
      package org.apache.maven.it0077;

      import junit.framework.TestCase;
      +import org.apache.commons.lang.BooleanUtils;

      public class PersonTwoTest
      extends PersonTest

      Results in:

      [INFO] ----------------------------------------------------------------------------
      [ERROR] BUILD FAILURE
      [INFO] ----------------------------------------------------------------------------
      [INFO] Compilation failure

      c:\maven-components\maven-core-it\it0077\sub2\src\test\java\org\apache\maven\it0077\PersonTwoTest.java:[4,31]
      package org.apache.commons.lang does not exist

      Attachments

        1. mng1378.tar.gz
          2 kB
          Lukas Nalezenec

        Issue Links

          Activity

            Set a better title. The problem here is that by design test dependencies are not transitive

            carlos Carlos Sanchez Gonzalez added a comment - Set a better title. The problem here is that by design test dependencies are not transitive

            changed the title as 'Make test dependencies transitive' is incorrect. Test dependencies
            are dependencies with scope test. test-jar dependencies are something totally different,
            and they can have scope compile.

            kenney Kenney Westerhof added a comment - changed the title as 'Make test dependencies transitive' is incorrect. Test dependencies are dependencies with scope test. test-jar dependencies are something totally different, and they can have scope compile.
            ltheussl Lukas Theussl added a comment -

            Attaching a simple test project as I just came across this. It doesn't cover all possible manifestations but is the simplest self-contained example that I could come up with. Running test in impl fails, uncommenting the util dependency (non test-jar) in impl's pom makes it pass. In practice I guess this bug is often masked by the fact that you also have a dependency on the corresponding main jar anyway.

            ltheussl Lukas Theussl added a comment - Attaching a simple test project as I just came across this. It doesn't cover all possible manifestations but is the simplest self-contained example that I could come up with. Running test in impl fails, uncommenting the util dependency (non test-jar) in impl's pom makes it pass. In practice I guess this bug is often masked by the fact that you also have a dependency on the corresponding main jar anyway.
            ittayd Ittay Dror added a comment -

            is there a workaround? right now this means I have to copy&paste all test dependencies. (I can't separate to an independent module since test-jar depends on classes in the module and the module's test depend on the test-jar)

            ittayd Ittay Dror added a comment - is there a workaround? right now this means I have to copy&paste all test dependencies. (I can't separate to an independent module since test-jar depends on classes in the module and the module's test depend on the test-jar)

            Any progress on this issue? As of 2.2.1 it does not seem to be fixed Â…
            I have exactly the same use case than Ittay and this is very annoying as the test-jar dependencies evolve.

            didierl Didier Loiseau (inactive) added a comment - Any progress on this issue? As of 2.2.1 it does not seem to be fixed Â… I have exactly the same use case than Ittay and this is very annoying as the test-jar dependencies evolve.
            w.ghelfi William Ghelfi added a comment -

            I have a (not so) slightly different use case and really would like to see this issue fixed...

            w.ghelfi William Ghelfi added a comment - I have a (not so) slightly different use case and really would like to see this issue fixed...
            alex.heneveld Alex Heneveld added a comment -

            +1

            Naively I expected that a dependency which is both test-scoped and test-jar-classified would pull in test-scoped transitive dependencies, ie given

            proj1 pom:
            <dependency>
              <artifactId>support</artifactId>
              <scope>test</scope>
            </dependency>
            
            proj2 pom:
            <dependency>
              <artifactId>proj1</artifactId>
              <classifer>test-jar</classifier>
              <scope>test</scope>
            </dependency>
            

            Like others I'd like proj2 to see support without having to explicitly re-list it.

            If I haven't declared classifier test-jar then it's fair enough not to pull in transitive test-scoped dependencies. I guess the problem is that classifier namespace isn't as formalised as scopes, and making dependency resolution itself dependent on the classifier name could get complicated?

            Would a new tag <importScope>test</importScope> be a good solution?

            (Although a part of me worries we this starts down a slippery slope, next wanting to introduce test-runtime and test-compile scopes...)

            alex.heneveld Alex Heneveld added a comment - +1 Naively I expected that a dependency which is both test-scoped and test-jar-classified would pull in test-scoped transitive dependencies, ie given proj1 pom: <dependency> <artifactId>support</artifactId> <scope>test</scope> </dependency> proj2 pom: <dependency> <artifactId>proj1</artifactId> <classifer>test-jar</classifier> <scope>test</scope> </dependency> Like others I'd like proj2 to see support without having to explicitly re-list it. If I haven't declared classifier test-jar then it's fair enough not to pull in transitive test-scoped dependencies. I guess the problem is that classifier namespace isn't as formalised as scopes, and making dependency resolution itself dependent on the classifier name could get complicated? Would a new tag <importScope>test</importScope> be a good solution? (Although a part of me worries we this starts down a slippery slope, next wanting to introduce test-runtime and test-compile scopes...)
            szubster Tomasz Szuba added a comment -

            What is the status of this issue?
            Is it even considered to implement this feature?

            szubster Tomasz Szuba added a comment - What is the status of this issue? Is it even considered to implement this feature?

            I'm amazed this issue has been open 7 years, it seems so basic.

            jpollak Josh Chaitin-Pollak added a comment - I'm amazed this issue has been open 7 years, it seems so basic.
            karlmdavis Karl M. Davis added a comment -

            For those still waiting on this, I recommend adopting the OSGi approach: separate test-only modules/projects. It's adds noise to the project structure, but is a cleaner separation. It has the added advantage of de-cluttering your project POMs and working around this issue.

            karlmdavis Karl M. Davis added a comment - For those still waiting on this, I recommend adopting the OSGi approach: separate test-only modules/projects. It's adds noise to the project structure, but is a cleaner separation. It has the added advantage of de-cluttering your project POMs and working around this issue.
            hiro2k Hugo Garza added a comment -

            I was able to solve this by moving my test dependencies into the parent POM that both projects share, but this isn't possible in every case.

            I guess the only thing I can do for now is to cast my vote for hopefully getting this feature implemented. I just learned about test-jar and was excited that it would just work but then I got my ClassNotFoundException and realized it was because of my missing transitive test dependencies.

            hiro2k Hugo Garza added a comment - I was able to solve this by moving my test dependencies into the parent POM that both projects share, but this isn't possible in every case. I guess the only thing I can do for now is to cast my vote for hopefully getting this feature implemented. I just learned about test-jar and was excited that it would just work but then I got my ClassNotFoundException and realized it was because of my missing transitive test dependencies.

            In my eyes tests are not public by any way
            It is interfaces and implementation that makes an artifact

            Therefore extending test cases is not something I would do.
            Not only should you make correct interfaces and implementation, now you also need to consider making tests so they can be extended ..
            This pattern would add complexity to an artifact.

            I find the system is designed correct as it is !
            -1

            aka3 Anders Kristian Andersen added a comment - In my eyes tests are not public by any way It is interfaces and implementation that makes an artifact Therefore extending test cases is not something I would do. Not only should you make correct interfaces and implementation, now you also need to consider making tests so they can be extended .. This pattern would add complexity to an artifact. I find the system is designed correct as it is ! -1

            Then I guess dependencies on test-jars should be completely disallowed. If your tests depend on some test-jar, and you don't have the dependencies of that test-jar, it is well possible that your tests cannot compile at all!

            It is not just a question of extending test cases, it could also be a question of reusing some other classes of the test-jar.

            For example, suppose you have module X and module Y which depends on X. In the test classes of module X, you implement a TestUtil class which relies on some other class of X's main classpath and on some class from a test-scoped dependency. Of course, the tests of X depend on TestUtil.

            Now, in the tests of module Y, you would like to reuse TestUtil. You thus need to declare a test-scoped dependency on X's test-jar. But for the moment you also have to redeclare all the test-scoped dependencies of X in order to use that class. And you cannot move that class somewhere else, due to its dependencies.

            didierl Didier Loiseau (inactive) added a comment - Then I guess dependencies on test-jars should be completely disallowed. If your tests depend on some test-jar, and you don't have the dependencies of that test-jar, it is well possible that your tests cannot compile at all! It is not just a question of extending test cases, it could also be a question of reusing some other classes of the test-jar. For example, suppose you have module X and module Y which depends on X. In the test classes of module X, you implement a TestUtil class which relies on some other class of X's main classpath and on some class from a test-scoped dependency. Of course, the tests of X depend on TestUtil . Now, in the tests of module Y, you would like to reuse TestUtil . You thus need to declare a test-scoped dependency on X's test-jar. But for the moment you also have to redeclare all the test-scoped dependencies of X in order to use that class. And you cannot move that class somewhere else, due to its dependencies.
            ansell Peter Ansell added a comment -

            One alternative if you need to depend on a testsuite that is published by a different module to ensure that the testsuite is published as a "jar", not a "test-jar", and it is pulled into "test" scope in the local module, with all of its dependencies. I have used this "testsuite-module" + "testrunner-module" pattern successfully in the past to publish both concrete and abstract testclasses, although generally only for compliance tests where a specific interface or protocol is being tested based on a well known specification.

            ansell Peter Ansell added a comment - One alternative if you need to depend on a testsuite that is published by a different module to ensure that the testsuite is published as a "jar", not a "test-jar", and it is pulled into "test" scope in the local module, with all of its dependencies. I have used this "testsuite-module" + "testrunner-module" pattern successfully in the past to publish both concrete and abstract testclasses, although generally only for compliance tests where a specific interface or protocol is being tested based on a well known specification.
            rebach Reto Gmuer added a comment -

            I agree with the last three comments. Write a test-utils artifact which can then be a test-scoped dependency of sub1 and sub2, test-utils will have commons-lang as a normal (compile-time) dependency.

            rebach Reto Gmuer added a comment - I agree with the last three comments. Write a test-utils artifact which can then be a test-scoped dependency of sub1 and sub2, test-utils will have commons-lang as a normal (compile-time) dependency.
            kramerthefirst John Kramer added a comment -

            +1

            I like to use a pattern with a pom only dependency project (i.e. no actual code or resources). This way I can easily unify a projects' dependencies-except for the test dependencies. Those can't be used because they have to be declared test scope (else they are packaged wrong). This transitivity would allow me to greatly simply my project structure (and no I don't use the anti-pattern of extending test cases).

            kramerthefirst John Kramer added a comment - +1 I like to use a pattern with a pom only dependency project (i.e. no actual code or resources). This way I can easily unify a projects' dependencies-except for the test dependencies. Those can't be used because they have to be declared test scope (else they are packaged wrong). This transitivity would allow me to greatly simply my project structure (and no I don't use the anti-pattern of extending test cases).
            kalgon Xavier Dury added a comment -

            After almost 15 years, it would be nice if some core maven maintainer could take a bit of time to think about this issue and give us a definitive answer/resolution.

            Thanks.

            PS: For my part, I would be happy with alex.heneveld's  solution to use an <importScope(s)> tag in the <dependency> element (which could default to 'compile' and be overridden with 'test' for test-jars).

            kalgon Xavier Dury added a comment - After almost 15 years, it would be nice if some core maven maintainer could take a bit of time to think about this issue and give us a definitive answer/resolution. Thanks. PS: For my part, I would be happy with alex.heneveld 's  solution to use an <importScope(s)> tag in the <dependency> element (which could default to 'compile' and be overridden with 'test' for test-jars).

            People

              Unassigned Unassigned
              markh Mark Hobson
              Votes:
              71 Vote for this issue
              Watchers:
              77 Start watching this issue

              Dates

                Created:
                Updated: