На днях я читал о ScalaTest . Мне понравилось, как выглядят тесты. И я начал думать, где его использовать. Сегодня ко мне пришел коллега и спросил, может ли он добавить несколько тестов к нашему небольшому инструменту, разработанному в Groovy. Это прозвенел звонок и превратился в призвание. Итак, вот лучшее решение для интеграции Groovy и ScalaTest.
Я начал с простого класса Groovy org.jboss.qa.SuperUtil (да, я парень по обеспечению качества JBoss ;-)) с одним статическим методом для добавления двух чисел. Класс находится в каталоге src.
def class SuperUtil { def static add(int a, int b) { return a + b } }
Во-вторых, я написал org.jboss.qa.test.SuperUtilSuite в соответствии с кратким описанием ScalaTest.
import org.scalatest._ import org.jboss.qa.SuperUtil class SuperUtilSuite extends FunSuite { test("SuperUtil add should return addition of two numbers") { assert(SuperUtil.add(2, 3) == 5) } }
Как видите, я напрямую импортировал класс Groovy.
У нас было два основных требования:
- Мы хотели иметь возможность запускать тесты из скрипта Groovy.
- Мы хотели избежать ненужных библиотек.
Итак, я начал с скрипта Groovy test.groovy с низким зависанием винограда:
@Grapes([ @Grab(group='org.scala-lang', module='scala-library', version='2.9.2'), @Grab(group='org.scalatest', module='scalatest_2.9.1', version='1.8'), ])
Я понял, что ScalaTest хочет только скомпилированные тестовые классы (есть ли способ обойти?). Чтобы иметь возможность скомпилировать SuperUtilSuite, я должен сначала скомпилировать SuperUtil. Так что все стало усложняться. В Groovy есть очень простой способ использования различных инструментов, таких как компиляторы, — AntBuilder. Давайте начнем с определения всех задач Ant, которые нам понадобятся.
def ant = new AntBuilder() ant.taskdef(name: 'groovyc', classname: 'org.codehaus.groovy.ant.Groovyc') ant.taskdef(resource: 'scala/tools/ant/antlib.xml') ant.taskdef(name: 'scalatest', classname: 'org.scalatest.tools.ScalaTestAntTask')
Ни одна из этих задач не может быть определена, потому что ни один из этих ресурсов не находится в пути к классам. Я должен добавить компилятор Scala в Grapes и заставить Grapes загружать классы с помощью системного загрузчика классов по умолчанию. Таким образом, обновленная конфигурация Grapes выглядит следующим образом:
@Grapes([ @Grab(group='org.scala-lang', module='scala-library', version='2.9.2'), @Grab(group='org.scalatest', module='scalatest_2.9.1', version='1.8'), @Grab(group='org.scala-lang', module='scala-compiler', version='2.9.2'), @GrabConfig(systemClassLoader = true) ])
Теперь я могу создавать целевые каталоги и компилировать классы Groovy.
ant.mkdir(dir: 'target/test-classes') ant.mkdir(dir: 'target/classes') ant.groovyc(srcdir: 'src', destdir: 'target/classes')
Не забудьте указать правильный пакет в ваших источниках. Я забыл об этом, и мне потребовалось некоторое время, чтобы понять, почему компилятор хранит класс непосредственно в target / classes. Какая глупая ошибка.
Составление тестового класса Scala не так просто. Для этого необходимы базовая библиотека Scala, библиотека ScalaTest, классы Groovy для тестирования и библиотека Groovy (например, класс Groovy обычно зависит от GroovyObject). Вопрос в том, как добавить зависимости, импортированные с помощью Grapes, и как добавить библиотеку Groovy.
Классы, импортированные с помощью Grapes, можно получить с помощью Grape.resolve (). Возвращает массив всех библиотек, импортированных с аннотациями @Grapes.
Существует два способа получения библиотеки Groovy. Можно также использовать Grapes, но со временем он может получить другую версию Groovy, чем для запуска скрипта, и это может привести к ужасным исключениям. Поэтому я решил непосредственно поискать groovy-all — *. Jar в каталоге $ GROOVY_HOME / embeddable. Мне не нужно вызывать динамический, поэтому я удалил файл jar с именем «indy» в его имени из classpath.
ant.scalac(srcdir: 'test', destdir: 'target/test-classes', fork: false) { classpath { pathelement(location: 'target/classes') fileset(dir: System.getenv('GROOVY_HOME') + '/embeddable') { include(name: 'groovy-all-*.jar') exclude(name: '*indy*') } Grape.resolve(new HashMap()).each { pathelement(location: new File(it).absolutePath) } } }
Наконец, я смог использовать задачу ScalaTest Ant для запуска теста. Это почти то же самое, что вызов компилятора Scala, но у него есть еще один элемент classpath — скомпилированные тестовые классы.
ant.scalatest(suite: 'org.jboss.qa.test.SuperUtilSuite') { runpath { pathelement(location: 'target/classes') pathelement(location: 'target/test-classes') fileset(dir: System.getenv('GROOVY_HOME') + '/embeddable') { include(name: 'groovy-all-*.jar') exclude(name: '*indy*') } Grape.resolve(new HashMap()).each { pathelement(location: new File(it).absolutePath) } } }
В итоге все прошло как положено.
[scalatest] Run starting. Expected test count is: 1 [scalatest] SuperUtilSuite: [scalatest] - SuperUtil add should return addition of two numbers [scalatest] Run completed in 115 milliseconds. [scalatest] Total number of tests run: 1 [scalatest] Suites: completed 1, aborted 0 [scalatest] Tests: succeeded 1, failed 0, ignored 0, pending 0 [scalatest] All tests passed.
Теперь я мог бы просто использовать некоторых авторов отчетов, и это все, ребята.
Вы можете получить полный исходный код от GitHub .