Статьи

Тестирование Groovy классов с помощью ScalaTest

На днях я читал о 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.

У нас было два основных требования:

  1. Мы хотели иметь возможность запускать тесты из скрипта Groovy.
  2. Мы хотели избежать ненужных библиотек.

Итак, я начал с скрипта 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 .