Запуск тестов из jar с помощью sbt testOnly в SBT?

В рамках настройки CI самым первым шагом является создание пакета/банки с использованием SBT dist. Следующие шаги заключаются в запуске модульных, интеграционных и функциональных тестов с dist созданным jar-файлом.

Возможно ли это сделать с помощью SBT?

Обычно я использую sbt testOnly "Unit.*", но это работает в контексте проекта. Я не могу найти документацию, показывающую, как это сделать, когда уже есть банка.

Я использую ScalaTest и знаю, что для него есть средство запуска, которое я мог бы использовать http://www.scalest.org/user_guide/using_the_runner. Но использование SBT было бы проще, если это возможно.

В качестве примера, что-то вроде этого, что я ищу:

sbt testOnly "Unit.* -jar myjar.jar"

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

sbt dist

?

ИЗМЕНИТЬ

  1. Я создал новую папку
  2. Я добавил build.sbt со следующим содержанием:

    name := "abc"
    
    version := "1.0-SNAPSHOT"
    
    scalaVersion := "2.10.0"
    
  3. Я добавил папку lib и скопировал в нее банку с тестами.

  4. Я побежал sbt testOnly Unit.*

  5. Тестов не нашел

ИЗМЕНИТЬ 2

Я попытался использовать следующий «правильный» файл SBT:

name := "ihs2tests"

version := "1.0-SNAPSHOT"

scalaVersion := "2.10.0"

unmanagedBase in Test := new java.io.File(".")

и переместил test.jar в корень проекта. Опять же, никаких тестов не найдено.


person user2668128    schedule 27.02.2014    source источник
comment
Это должно помочь вам начать работу: stackoverflow.com/a/16409096/2197460.   -  person Dave Swartz    schedule 28.02.2014
comment
Тестовый код обычно не включается в dist jar-файлы, но ссылка @DaveSwartz может помочь в этом.   -  person Rob Starling    schedule 03.03.2014
comment
А как насчет sbt test:dist? Разве это не включает тесты в (тестовой) дистрибутивной банке?   -  person Jacek Laskowski    schedule 03.03.2014


Ответы (2)


Обычно я использую sbt testOnly "Unit.*", но это работает в контексте проекта. Я не могу найти документацию, показывающую, как это сделать, когда уже есть банка.

Задачи семейства test в SBT (с testOnly в качестве примера) работают с задачей compile, которая возвращает список скомпилированных файлов через экземпляр sbt.inc.Analysis. Я не мог понять, как изменить его и внедрить измененный экземпляр Analysis в testOnly, чтобы он знал, что тест, который я собираюсь запустить, существует.

Я предлагаю другое решение - трюк.

Упакуйте классы тестов в банку с задачей test:package следующим образом:

[test-lib]> test:package
[info] Updating {file:/Users/jacek/sandbox/so/test-lib/}test-lib...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Compiling 1 Scala source to /Users/jacek/sandbox/so/test-lib/target/scala-2.10/test-classes...
[info] Packaging /Users/jacek/sandbox/so/test-lib/target/scala-2.10/test-lib_2.10-0.1-SNAPSHOT-tests.jar ...
[info] Done packaging.
[success] Total time: 9 s, completed Mar 4, 2014 11:34:13 PM

Когда у вас есть тестовая банка, вы можете выполнить тестовую среду в командной строке без SBT (я предполагаю, что вы используете ScalaTest с учетом scalest, но я буду использовать Specs2). Прочтите документацию по тестовой среде, чтобы узнать, как это сделать, а для Specs2 это specs2.run, как описано в Консольный вывод.

Выполнение тестов из тестовой банки требует определения правильного ПУТИ К КЛАССУ, который может быть или не быть легко правильным. Вот где SBT может быть очень полезен — для управления зависимостями и, следовательно, CLASSPATH.

Создайте еще один проект SBT и сохраните тестовый файл jar в подкаталоге lib, чтобы он был в CLASSPATH (как описано в Неуправляемые зависимости).

Зависимости в lib идут по всем путям к классам (для компиляции, тестирования, запуска и консоли).

Добавьте пример build.sbt, в котором вы определяете свою тестовую среду как зависимость от проекта. Для Specs2 это выглядит следующим образом (я использовал конфигурацию по умолчанию, как описано на домашней странице Specs2):

libraryDependencies += "org.specs2" %% "specs2" % "2.3.8" % "test"

scalacOptions in Test ++= Seq("-Yrangepos")

Хитрость заключается в том, чтобы выполнить основной класс тестовой среды, например. specs2.run для Specs2, как если бы класс выполнялся в командной строке. SBT помогает с test:runMain.

[my-another-project]> test:runMain specs2.run HelloWorldSpec
[info] Running specs2.run HelloWorldSpec
HelloWorldSpec

The 'Hello world' string should
+ contain 11 characters
+ start with 'Hello'
+ end with 'world'

Total for specification HelloWorldSpec
Finished in 62 ms
3 examples, 0 failure, 0 error

Exception: sbt.TrapExitSecurityException thrown from the UncaughtExceptionHandler in thread "run-main-0"
[success] Total time: 5 s, completed Mar 4, 2014 11:15:14 PM

Не беспокойтесь об этом Exception, поскольку он исходит от SBT, который перехватывает exit из Specs2 (после выполнения теста), поэтому SBT остается в рабочем состоянии.

person Jacek Laskowski    schedule 02.03.2014
comment
Я скопировал свой build.sbt и test.jar в новый проект, но он попытался скомпилировать его снова, так что, к сожалению, это не работает. - person user2668128; 03.03.2014
comment
Попробуйте еще раз! - person Jacek Laskowski; 05.03.2014

Похоже, что SBT не может прочитать файл jar без какой-либо дополнительной/ручной настройки - я могу ошибаться, но я ничего не нашел в документах. Поэтому я попробовал что-то вроде этого, чтобы упростить задачу:

unzip some-test.jar

java -jar sbt-launch.jar \
  'set scalaSource in Test := new java.io.File(".")' \
  'set fullClasspath in Test += Attributed.blank(file("."))' \
  'test'

Это работает без ошибок, но не находит тесты.

Если я добавлю 'set includeFilter in (Test, unmanagedSources) := "*Suite*.class"', чтобы заставить его искать тесты, он, очевидно, потерпит неудачу, потому что он ожидает *.scala файлов, а не скомпилированных *.class файлов.

Я не эксперт SBT, но я думаю, что это должно быть близко к решению. Должен быть способ программно прочитать все файлы из пути jar, а затем указать тестовой среде использовать файлы *.class.

На данный момент кажется более разумным запускать тесты с помощью средства запуска тестов Scalatest или из sbt с использованием проекта.

Если вы хотите копнуть глубже, взгляните на исходный код SBT и стандартный сценарий оболочки sbt, который выполняет множество настроек перед запуском jar-файла запуска sbt.

person yǝsʞǝla    schedule 28.02.2014