Как гарантировать одинаковые версии библиотеки для конфигураций Compile и Test - PullRequest
1 голос
/ 15 апреля 2019

У меня есть проект среднего размера sbt (~ 20 подпроектов, ~ 50 прямых зависимостей, ~ 400 переходных зависимостей). Я готовлю проект для включения юнит-тестирования [0]. Я столкнулся со странными проблемами и заметил, что точные версии, используемые для определенных зависимостей, отличаются для целей Compile и Test, то есть модульные тесты (sbt test) выполняются с версиями библиотек, отличными от проекта напрямую (* 1006) *).

Я создал diff между выходными данными sbt Compile/dependencyList [1] и sbt Test/dependencyList и вижу около 50 зависимостей с различными версиями. Я знаю, что могу использовать настройки dependencyOverride, но это нецелесообразно делать вручную для сотен зависимостей. Мне также придется обновлять этот список каждый раз, когда мы хотим обновить наши прямые зависимости.

Каков предполагаемый способ справиться с этой ситуацией? То есть как я могу убедиться, что использую те же версии зависимостей во время модульных тестов, что и при работе в рабочей среде?

[0]: лучше поздно, чем никогда! :)

[1]: dependencyList - это команда из sbt-dependency-graph .

1 Ответ

1 голос
/ 15 апреля 2019

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

Добавьте sbt-assembly к плагинам и затем определите следующую пользовательскую команду:

commands += Command.command("testWithFatJar") { state =>
    "set assembly / test := {}" ::
    "assembly" ::
    "set Test / fullClasspath := Attributed.blank((assembly / assemblyOutputPath).value) :: (Test / fullClasspath).value.toList" ::
    "test" :: state
}

Обратите внимание, как мы сначала собираем толстый сосуд, а затем добавляем его к тестовому пути к классам с помощью

Test / fullClasspath := Attributed.blank((assembly / assemblyOutputPath).value) :: (Test / fullClasspath).value.toList

так, чтобы он находился в первой позиции.Здесь мы используем свойство упорядочения путей к классам JVM свойство

Порядок, в котором вы указываете несколько записей путей к классам, важен.Интерпретатор Java будет искать классы в каталогах в порядке их появления в переменной пути к классу

, что означает, что если у нас есть одинаковые классы в пути к классам, то будет использоваться первый встреченный класс.

Расположение баночки жира обеспечивается задачей assemblyOutputPath:

inspect assembly::assemblyOutputPath
[info] Task: java.io.File
[info] Description:
[info]  output path of the fat jar

Теперь при выполнении testWithFatJar должен запускаться следующий тестовый путь:

sbt:how-to-guarantee-same-library-versions-for-compile-and-test-configurations> show Test / fullClasspath
[info] * Attributed(/Users/mario_galic/code/stackoverflow/how-to-guarantee-same-library-versions-for-compile-and-test-configurations/target/scala-2.12/how-to-guarantee-same-library-versions-for-compile-and-test-configurations-assembly-0.1.0-SNAPSHOT.jar)
[info] * Attributed(/Users/mario_galic/code/stackoverflow/how-to-guarantee-same-library-versions-for-compile-and-test-configurations/target/scala-2.12/test-classes)
[info] * Attributed(/Users/mario_galic/code/stackoverflow/how-to-guarantee-same-library-versions-for-compile-and-test-configurations/target/scala-2.12/classes)
[info] * Attributed(/Users/mario_galic/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.8.jar)
[info] * Attributed(/Users/mario_galic/.ivy2/cache/org.scalatest/scalatest_2.12/bundles/scalatest_2.12-3.0.5.jar)
[info] * Attributed(/Users/mario_galic/.ivy2/cache/org.scalactic/scalactic_2.12/bundles/scalactic_2.12-3.0.5.jar)
[info] * Attributed(/Users/mario_galic/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.12.8.jar)
[info] * Attributed(/Users/mario_galic/.ivy2/cache/org.scala-lang.modules/scala-xml_2.12/bundles/scala-xml_2.12-1.0.6.jar)

Обратите внимание, как *-assembly-0.1.0-SNAPSHOT.jar находится в первой позиции.Как только мы подтвердим, что ад является зависимостью, мы можем начать думать, какие постоянные модификации сборки необходимы для ее устранения.

...