218 votes

Dépendances de test multi-projets avec gradle

J'ai une configuration multi-projets et je veux utiliser gradle.

Mes projets sont comme ceci :

  • Projet A

    • -> src/main/java
    • -> src/test/java
  • Projet B

    • -> src/main/java (dépend de src/main/java en Projet A )
    • -> src/test/java (dépend de src/test/java en Projet A )

Mi Projet B build.gradle est comme ceci :

apply plugin: 'java'
dependencies {
  compile project(':ProjectA')
}

La tâche compileJava fonctionnent très bien mais le compileTestJava ne compile pas le fichier de test de Projet A .

2 votes

157voto

Fesler Points 224

Déclassé - Pour Gradle 5.6 et plus, utilisez cette réponse .

En Projet B il suffit d'ajouter un testCompile dépendance :

dependencies {
  ...
  testCompile project(':A').sourceSets.test.output
}

Testé avec Gradle 1.7.

9 votes

Il s'avère que la propriété classes est dépréciée -- utilisez output à la place.

12 votes

Cela ne fonctionne pas dans Gradle 1.3 puisque sourceSets n'est plus une propriété publique d'un projet.

3 votes

Gardez à l'esprit que la solution ci-dessus nécessite au moins une gradle testClasses avant que la structure de construction ne soit réellement valide. Par exemple, le plugin Eclipse ne vous permettra pas d'importer le projet avant cela. C'est vraiment dommage testCompile project(':A') ne fonctionne pas. @DavidPärsson : "Gradle 1.3" contredit "plus du tout" puisque Fesler a testé avec Gradle 1.7.

70voto

Nikita Skvortsov Points 1514

Le moyen le plus simple est d'ajouter une dépendance de tâche explicite dans le projet B :

compileTestJava.dependsOn tasks.getByPath(':ProjectA:testClasses')

Le moyen le plus difficile (mais le plus clair) est de créer une configuration d'artefact supplémentaire pour le ProjetA :

task myTestsJar(type: Jar) { 
  // pack whatever you need...
}

configurations {
  testArtifacts
}

artifacts {
   testArtifacts myTestsJar
}

et ajoutez le testCompile dépendance pour le projet B

apply plugin: 'java'
dependencies {
  compile project(':ProjectA')
  testCompile project(path: ':ProjectA', configuration: 'testArtifacts')
}

4 votes

J'ai essayé ceci (la manière simple) et bien que cela assure la construction des testClasses, cela n'ajoute pas le chemin du test au CLASSPATH, donc mes tests ProjectB qui dépendent des classes de test ProjectA ne se construisent toujours pas.

0 votes

La méthode difficile ne fonctionne pas pour moi, en utilisant Gradle 1.8 : Aucune signature de la méthode : org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler.testArtifacts() n'est applicable pour les types d'arguments : (org.gradle.api.tasks.bundling.Jar_Decorated) valeurs : [tâche ':projectA:myTestsJar']. L'erreur est signalée pour la ligne "testArtifacts myTestsJar".

1 votes

@dmoebius vous devez ajouter testArtifacts configuration comme celle-ci : configurations { testArtifacts } Pour plus de détails, voir cette section de l'aide Gradle : gradle.org/docs/current/dsl/

25voto

Martin Snyder Points 122

J'ai rencontré ce problème moi-même récemment, et il est difficile de trouver des réponses à ces questions.

L'erreur que vous commettez est de penser qu'un projet doit exporter ses éléments de test de la même manière qu'il exporte ses artefacts primaires et ses dépendances.

Personnellement, j'ai eu beaucoup plus de succès avec la création d'un nouveau projet dans Gradle. Dans votre exemple, je l'aurais nommé

Projet A_Test -> src/main/java

Je mettrais dans src/main/java les fichiers que vous avez actuellement dans Project A/src/test/java. Faites en sorte que toutes les dépendances testCompile de votre Projet A compilent les dépendances du Projet A_Test.

Ensuite, faites du projet A_Test une dépendance testCompile du projet B.

Ce n'est pas logique si l'on se place du point de vue de l'auteur des deux projets, mais je pense que cela a beaucoup de sens si l'on pense à des projets comme junit et scalatest (et d'autres). Même si ces frameworks sont liés aux tests, ils ne sont pas considérés comme faisant partie des cibles de "test" dans leurs propres frameworks - ils produisent des artefacts primaires que d'autres projets utilisent par hasard dans leur configuration de test. Vous voulez simplement suivre ce même modèle.

Essayer de faire les autres réponses listées ici n'a pas fonctionné pour moi personnellement (en utilisant Gradle 1.9), mais j'ai trouvé que le modèle que je décris ici est une solution plus propre de toute façon.

0 votes

Oui, j'ai opté pour cette approche à la fin de la journée.

0 votes

C'est la meilleure approche ! Sauf que je garderais le code de test dans le projet A et déplacerais seulement les dépendances pour A src/test/java et B src/test/java vers A_Test. Puis faire du projet A_Test une dépendance testImplementation de A et B.

22voto

Dominik Pawlak Points 9

Je sais que c'est une vieille question mais je viens d'avoir le même problème et j'ai passé du temps à comprendre ce qui se passe. J'utilise Gradle 1.9. Tous les changements doivent être dans le fichier de ProjectB build.gradle

Pour utiliser les classes de test du projet A dans les tests du projet B :

testCompile files(project(':ProjectA').sourceSets.test.output.classesDir)

Pour s'assurer que sourceSets est disponible pour le projet A :

evaluationDependsOn(':ProjectA')

Pour s'assurer que les classes de test de ProjectA sont réellement là, quand vous compilez ProjectB :

compileTestJava.dependsOn tasks.getByPath(':ProjectA:testClasses')

2 votes

Cela a également fonctionné pour moi, sauf que j'ai dû omettre le .classesDir .

0voto

John Caron Points 31

Dans le projet B :

dependencies {
  testCompile project(':projectA').sourceSets.test.output
}

Semble fonctionner dans la version 1.7-rc-2

2 votes

Cela crée également des complications inutiles dans la gestion du projet par Eclipse. La solution proposée par @NikitaSkvortsov est préférable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X