Многопроектные тестовые зависимости с Gradle

build dependencies gradle

53762 просмотра

12 ответа

815 Репутация автора

У меня есть многопроектная конфигурация, и я хочу использовать gradle.

Мои проекты такие:

  • Проект А

    • -> src/main/java
    • -> src/test/java
  • Проект Б

    • -> src/main/java(зависит src/main/javaот проекта A )
    • -> src/test/java(зависит src/test/javaот проекта A )

Файл моего проекта B build.gradle выглядит так:

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

Задача compileJavaработы большой , но compileTestJavaне компилировать тестовый файл из проекта A .

Автор: mathd Источник Размещён: 13.04.2011 03:17

Ответы (12)


49 плюса

3870 Репутация автора

Простой способ - добавить явную зависимость задачи в ProjectB:

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

Сложный (но более понятный) способ - создать дополнительную конфигурацию артефактов для ProjectA:

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

configurations {
  testArtifacts
}

artifacts {
   testArtifacts myTestsJar
}

и добавьте testCompileзависимость для ProjectB

apply plugin: 'java'
dependencies {
  compile project(':ProjectA')
  testCompile project(path: ':ProjectA', configuration: 'testArtifacts')
}
Автор: Nikita Skvortsov Размещён: 13.04.2011 11:40

103 плюса

1135 Репутация автора

Решение

Устаревшие

В проекте B вам просто нужно добавить testCompileзависимость:

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

Протестировано с Gradle 1.7.

Автор: Fesler Размещён: 01.11.2011 04:07

-1 плюса

37 Репутация автора

в проекте B:

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

Кажется, работает в 1.7-RC-2

Автор: John Caron Размещён: 06.08.2013 09:43

13 плюса

303 Репутация автора

Я недавно столкнулся с этой проблемой, и человек - это трудные вопросы, чтобы найти ответы на них.

Ошибка, которую вы совершаете, состоит в том, что вы думаете, что проект должен экспортировать свои тестовые элементы так же, как он экспортирует свои основные артефакты и зависимости.

То, с чем я лично добился гораздо большего успеха, - это создание нового проекта в Gradle. В вашем примере я бы назвал это

Проект A_Test -> src / main / java

Я бы поместил в src / main / java файлы, которые у вас сейчас есть в Project A / src / test / java. Сделайте любые зависимости testCompile вашего Project A зависимости компиляции Project A_Test.

Затем сделайте Project A_Test зависимостью testCompile проекта B.

Это не логично, когда вы подходите к этому с точки зрения автора обоих проектов, но я думаю, что это имеет смысл, когда вы думаете о таких проектах, как junit и scalatest (и другие. Даже если эти инфраструктуры связаны с тестированием, они не считаются частью «тестовых» целей в их собственных инфраструктурах - они создают основные артефакты, которые другие проекты используют в своей тестовой конфигурации. Вы просто хотите следовать той же схеме.

Попытка сделать другие ответы, перечисленные здесь, не сработала лично для меня (используя Gradle 1.9), но я обнаружил, что шаблон, который я здесь описываю, в любом случае является более чистым решением.

Автор: Martin Snyder Размещён: 31.01.2014 04:13

17 плюса

647 Репутация автора

Я знаю, что это старый вопрос, но у меня была та же проблема, и я потратил некоторое время на выяснение того, что происходит. Я использую Gradle 1.9. Все изменения должны быть в ProjectB'sbuild.gradle

Чтобы использовать тестовые классы из ProjectA в тестах ProjectB:

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

Чтобы убедиться, что sourceSetsсвойство доступно для ProjectA:

evaluationDependsOn(':ProjectA')

Чтобы убедиться, что тестовые классы из ProjectA действительно присутствуют при компиляции ProjectB:

compileTestJava.dependsOn tasks.getByPath(':ProjectA:testClasses')
Автор: Dominik Pawlak Размещён: 05.02.2014 02:47

11 плюса

366 Репутация автора

Новое решение на основе testJar (поддерживается trnsitive зависимость), доступное как плагин gradle:

https://github.com/hauner/gradle-plugins/tree/master/jartest

https://plugins.gradle.org/plugin/com.github.hauner.jarTest/1.0

Из документации

Если у вас многопроектная сборочная сборка, у вас могут быть тестовые зависимости между подпроектами (что, вероятно, является намеком на то, что ваши проекты плохо структурированы).

Например, предположим, что проект, в котором подпроект Project B зависит от Project A и B, имеет не только зависимость компиляции от A, но также и тестовую зависимость. Для компиляции и запуска тестов B нам понадобятся несколько вспомогательных классов test из A.

По умолчанию Gradle не создает JAR-артефакт из результатов тестовой сборки проекта.

Этот плагин добавляет конфигурацию testArchives (на основе testCompile) и задачу jarTest для создания jar из набора тестовых источников (с добавлением теста классификатора к имени jar). Затем мы можем полагаться в B на конфигурацию testArchives для A (которая также будет включать транзитивные зависимости A).

В A мы добавим плагин для build.gradle:

apply plugin: 'com.github.hauner.jarTest'

В B мы ссылаемся на конфигурацию testArchives следующим образом:

dependencies {
    ...
    testCompile project (path: ':ProjectA', configuration: 'testArchives') 
}
Автор: demon101 Размещён: 30.12.2015 11:58

1 плюс

1584 Репутация автора

Некоторые из других ответов так или иначе вызывали ошибки - Gradle не обнаружил тестовые классы из других проектов или проект Eclipse имел недопустимые зависимости при импорте. Если у кого-то есть такая же проблема, я предлагаю перейти с:

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

Первая строка заставляет Eclipse связывать другой проект как зависимость, поэтому все источники включены и обновлены. Второй позволяет Gradle фактически видеть источники, не вызывая при этом каких-либо недопустимых ошибок зависимости, как это testCompile project(':core').sourceSets.test.outputделает.

Автор: JustACluelessNewbie Размещён: 24.05.2016 08:14

7 плюса

491 Репутация автора

Пожалуйста, прочтите обновление ниже.

Подобные проблемы, описанные JustACluelessNewbie, возникают в IntelliJ IDEA. Проблема в том, что зависимость на testCompile project(':core').sourceSets.test.outputсамом деле означает: «зависеть от классов, сгенерированных задачей сборки gradle». Поэтому, если вы откроете чистый проект, где классы еще не созданы, IDEA не распознает их и сообщит об ошибке.

Чтобы решить эту проблему, вы должны добавить зависимость от тестовых исходных файлов рядом с зависимостью от скомпилированных классов.

// First dependency is for IDEA
testCompileOnly files { project(':core').sourceSets.test.java.srcDirs }
// Second is for Gradle
testCompile project(':core').sourceSets.test.output

Вы можете наблюдать зависимости, распознаваемые IDEA, в Настройках модуля -> Зависимости (область тестирования) .

Btw. Это не очень хорошее решение, поэтому стоит подумать о рефакторинге. Сам Gradle имеет специальный подпроект, содержащий только классы поддержки тестирования. См. Https://docs.gradle.org/current/userguide/test_kit.html.

Обновление 2016-06-05 Подробнее Я думаю о предлагаемом решении меньше, мне нравится. Есть несколько проблем с этим:

  1. Это создает две зависимости в IDEA. Один указывает на тестирование источников, другой на скомпилированные классы. И крайне важно, в каком порядке эти зависимости признаются IDEA. Вы можете поиграть с ним, изменив порядок зависимостей в Настройках модуля -> вкладка Зависимости.
  2. Объявляя эти зависимости, вы излишне загрязняете структуру зависимостей.

Так какое же решение лучше? На мой взгляд, это создание нового пользовательского набора исходных кодов и добавление в него общих классов. На самом деле авторы проекта Gradle сделали это, создав исходный набор testFixtures.

Для этого вам просто нужно:

  1. Создайте исходный набор и добавьте необходимые конфигурации. Проверьте этот плагин сценария, используемый в проекте Gradle: https://github.com/gradle/gradle/blob/v4.0.0/gradle/testFixtures.gradle
  2. Объявите правильную зависимость в зависимом проекте:

    dependencies {
        testCompile project(path: ':module-with-shared-classes', configuration: 'testFixturesUsageCompile')
    }
    
  3. Импортируйте проект Gradle в IDEA и используйте опцию «создать отдельный модуль для исходного набора» при импорте.
Автор: Václav Kužel Размещён: 24.05.2016 08:50

5 плюса

6612 Репутация автора

Решение Феслера не сработало для меня, когда я попытался построить проект для Android (версия 2.2.0). Поэтому мне пришлось ссылаться на необходимые классы вручную:

android {
    sourceSets {
        androidTest {
            java.srcDir project(':A').file("src/androidTest/java")
        }
        test {
            java.srcDir project(':A').file("src/test/java")
        }
    }
}
Автор: Beloo Размещён: 05.10.2016 08:13

0 плюса

139 Репутация автора

Если у вас есть фиктивные зависимости, которые вам нужно разделить между тестами, вы можете создать новый проект, projectA-mockа затем добавить его в качестве тестовой зависимости ProjectAи ProjectB:

dependencies {
  testCompile project(':projectA-mock')
}

Это ясно решение разделить имитировали зависимостей, но если вам нужно запустить тесты из ProjectAв ProjectBиспользовании другого решения.

Автор: sylwano Размещён: 14.05.2018 10:46

1 плюс

646 Репутация автора

Я так опоздал на вечеринку (теперь это Gradle v4.4), но для всех, кто найдет это:

Перейдите к build.gradle проекта B (который нуждается в нескольких тестовых классах из A) и добавьте следующее:

sourceSets {
    String sharedTestDir = "${projectDir}"+'/module-b/src/test/java'
    test {
        java.srcDir sharedTestDir
    }
}

Вуаля!

Автор: tricknology Размещён: 22.06.2018 12:11

1 плюс

51 Репутация автора

Если вы хотите использовать зависимости артефактов, чтобы:

  • Исходные классы ProjectB зависят от исходных классов Project A
  • Тестовые классы ProjectB зависят от тестовых классов Project A

тогда раздел зависимостей ProjectB в build.gradle должен выглядеть примерно так:

dependencies {

  compile("com.example:projecta:1.0.0")

  testCompile("com.example:projecta:1.0.0:tests")

}

Для того, чтобы это работало, ProjectA необходимо создать jar -tests и включить его в артефакты, которые он создает.

Файл build.gradle в ProjectA должен содержать следующую конфигурацию:

task testsJar(type: Jar, dependsOn: testClasses) {
    classifier = 'tests'
    from sourceSets.test.output
}

configurations {
    tests
}

artifacts {
    tests testsJar
    archives testsJar
}

jar.finalizedBy(testsJar)

Когда артефакты ProjectA будут опубликованы в вашей артефакте, они будут содержать банку -test .

TestCompile в зависимости разделе ProjectB принесет в классах в - тестах баночки.


Если вы хотите включить исходный и тестовый классы ProjectA в ProjectB для целей разработки, то раздел зависимостей в build.gradle в ProjectB будет выглядеть следующим образом:

dependencies {

  compile project(':projecta')

  testCompile project(path: ':projecta', configuration: 'tests')

}
Автор: Joman68 Размещён: 11.02.2019 11:54
Вопросы из категории :
32x32