Статьи

Использование Groovy — мягкое введение

Groovy является объектно-ориентированным языком программирования для платформы Java и может использоваться в качестве языка сценариев. Большинство из нас, но вместо того, чтобы использовать только Groovy , мы используем Grails (веб-фреймворк на основе Groovy ) для разработки веб-приложений.

Но Groovy может использоваться автономно для разработки ваших внутренних инструментов. Позвольте мне объяснить, почему скрипты Groovy упростили нашу разработку инструментов для генерации данных для интеграционных тестов.
В моей компании мы создаем клинические инструменты. Эти инструменты настолько дорогие и достаточно большие, что говорят, что они не портативны. По этим причинам у каждого инструмента есть эмулятор , поэтому интеграционные тесты выполняются без физического инструмента.

Наш эмулятор имеет XML- файл, в котором сконфигурированы все необходимые ресурсы для запуска тестов. В итоге каждый файл содержит список штрих-кодов крови и штрих-кодов реагентов. В нашем случае штрих-коды имеют значение (вид ресурса, срок действия, контрольная сумма,…).

Поэтому можно подумать о создании стандартного файла конфигурации, который используется в интеграционных тестах. Это хорошая идея, если вы не знаете, что срок годности выражается в месяцах. Итак, однажды, не зная точно, почему ваши тесты начинают проваливаться. Ответ очевиден, ресурсы истекли. Нам нужен ( скрипт ?), Который обновляет этот XML- файл, поэтому, когда ресурс истекает, его поле месяца изменяется.

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

Поскольку проект разрабатывается на Java , можно подумать о создании небольшого класса Java, который выполняет всю эту работу. Но подождите и подумайте, будет ли этот класс маленьким или нет, нам нужен парсер ( DocumentBuilder ), метод, который обходит все узлы и проверяет, истек ли ресурс ( NodeList, Element.getAttribute () ,…), и, наконец, пишет изменения в файл. Кроме того, некоторые штрих-коды содержат специальные символы, которые следует обнаруживать с помощью регулярного выражения ( Pattern , Matcher ), чтобы избежать его обновления. Хотя этот класс не сложный, он далеко от небольшого класса с несколькими строками.

Но как насчет программирования полиглота? Groovy может быть выбором. Давайте посмотрим, как Groovy работает с XML и регулярными выражениями .

Представьте себе следующий XML- файл:

1
2
3
4
5
6
7
8
9
<InstrumentContents>
     <SampleHolder11>
          <Samples>
               <Sample diameter="10" barcode="A1"/>
        <Sample diameter="10" barcode="2"/>
        <Sample diameter="10" barcode="3"/>
          </Samples>
     </SampleHolder11>
</InstrumentContents>

Groovy и XML

Тем временем в Java вы создаете DocumentBuilderFactory, который возвращает DocumentBuilder , а затем вызываете метод разбора в Groovy так же просто, как:

1
def root = new XmlParser().parseText(input)

и корневая переменная указывает на корневой элемент файла XML.

А теперь представьте, что вы хотите обновить все штрих-коды крови данного держателя. В Java вы будете использовать итератор над NodeList или выражение XPath . Вижу простоту с Groovy .

1
2
3
4
5
6
def samples = root.SampleHolder11.Samples.Sample.findAll();
 
samples.each { sample ->
                   def barcode = nextBarcode()
            sample.@barcode = barcode
              }

Обратите внимание, что в Groovy узлы рассматриваются как атрибуты объекта, и, наконец, мы вызываем метод findAll (), который возвращает список образцов узлов, принадлежащих тегу SampleHolder11 . Для возврата значения атрибута так же просто, как добавить символ @ перед именем атрибута, в нашем случае штрих-код .

И для написания XML так же просто, как:

1
2
3
def writer = new StringWriter()
new XmlNodePrinter(new PrintWriter(writer)).print(root)
println writer.toString()

В предыдущем примере вывод записывается в консоль.

Groovy и регулярные выражения

Помните, что некоторые штрих-коды имеют специальный формат. В нашем случае, если какой-либо штрих-код начинается с A , B , C или D , не следует изменять. Чистое, повторно используемое и поддерживаемое решение использует регулярные выражения, чтобы проверить, соответствует ли один штрих-код или нет специального формата. В Java этот процесс не банален, вы должны создать объект Pattern с регулярным выражением, Matcher и использовать метод find (), чтобы увидеть, найден ли шаблон в записи или нет.

Но как мы можем определить, соответствует ли одна строка регулярному выражению в Groovy ? == ~ оператор делает работу за нас. Скажите мне, что вы думаете об этом выражении:

1
2
3
4
5
def currentBarcode = sample.@Barcode as String
 
if( currentBarcode ==~/([ABCD]).+/ ) {
     ...
}

Elementary. Вы согласитесь со мной, что Groovy более прост, чем Java . Для указания шаблона вы должны использовать только символ ~ и косую черту   ( / ) затем регулярное выражение и, наконец, косая черта для разграничения. Но Groovy также поддерживает = ~ (создать Matcher ) и == ~ (возвращает логическое значение, соответствует ли String шаблону).

Я думаю, что создание сценария, который читает / анализирует / записывает XML- файл, является настолько быстрым и легким, что не требуется много классов по сравнению с Java . И не стоит сравнивать с подходом регулярных выражений , в Groovy это самый простой способ, которым можно подумать.

После успеха предыдущего скрипта Groovy мы решили создать еще один инструмент (скрипт Groovy ) для управления базой данных.

Система регистрирует в базе данных все случаи, произошедшие при выполнении. Некоторые случаи легко воспроизвести с помощью эмулятора, а другие нет. В интеграционных тестах проблем нет, поскольку используется база данных с заданным заполнением, но приемочные тесты не содержат данных и генерируются при выполнении тестов. Но поскольку есть некоторые инциденты, которые трудно воспроизвести в эмуляторе, создается сценарий Groovy для вставки инцидентов.

Groovy и SQL

Как и Java , Groovy может также получить доступ к базам данных и, как вы можете предположить, простым способом. Нет объекта подключения , нет PreparedStatement , нет ResultSet ,….

Давайте рассмотрим пример поиска данных и их использования для создания нового реестра. Представьте, что у нас есть таблица с именем « Выполнение» и еще одна с именем « Заболеваемость» и отношения « один ко многим» .

01
02
03
04
05
06
07
08
09
10
11
12
def db = Sql.newInstance(databaseUrl, user, password,  driverClass)
 
def findExecutionByNameSql = "SELECT * FROM execution as e WHERE e.name=?"
def insertIncidenceSql = "INSERT INTO incidence VALUES(?,?,?)"
 
def name = "myExecution"
def incidence = "NOT_DISPENSED"
 
db.eachRow(findExecutionByNameSql, [name]) { execution ->
  def nextval = nextval();
  db.execute(insertIncidenceSql, [nextval, incidence, execution.dboid])
 }

Просто да? Одной линией установлено соединение с базой данных.

Выполнение запроса SELECT и повторение результатов также просты. Используя метод eachRow , все результаты повторяются. Объект ResultSet больше не требуется. Значения параметров передаются в квадратных скобках ([]), и в виде XML доступ к каждой строке осуществляется с помощью Closure . В предыдущем примере каждая строка отображается в переменную выполнения. Кроме того, посмотрите, насколько легко читается значение каждого кортежа. Как и в XML, вы получаете доступ к значению как атрибуту класса, больше нет получателей методов ResultSet , в примере execute.dboid используется для ссылки на поле dboid .

Наконец, метод execute используется для обновления базы данных.

Теперь, когда я показал вам некоторые интересные функции, которые предлагает нам Groovy , я объясню вам, как мы выполняем эти инструменты.

GMaven

Мы используем Jenkins с Maven в качестве системы интеграции Continuos . Перед тем, как Дженкинс начнет выполнять интеграционные тесты , скрипты Groovy выполняются, поэтому эмулятор настроен правильно. Интересной частью этого шага является то, как pom настроен для выполнения скриптов Groovy .

Существует плагин под названием gmaven-plugin . Этот плагин запускает скрипты Groovy в зависимости от фазы и цели.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<build>
       <plugins>
 
                  <plugin>
 
                        <groupId>org.codehaus.groovy.maven</groupId>
 
                        <artifactId>gmaven-plugin</artifactId>
 
                        <executions>
 
                             <execution>
 
                                  <phase>process-test-resources</phase>
 
                                  <goals>
 
                                       <goal>execute</goal>
 
                                  </goals>
 
                                  <configuration>
 
                                        <source>${pom.basedir}/src/main/script/contents.groovy</source>
 
                                  </configuration>
 
                            </execution>
 
                        </executions>
 
                  </plugin>
 
     </plugins>
 
</build>

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

В заключение я хочу сказать, что я большой поклонник Java, и я не собираюсь его критиковать, но думаю, что есть некоторые проблемы, которые лучше всего подходят для использования других языков, а не Java . Мой совет — изучать как можно больше языков ( Scala , Groovy ,…), чтобы как программист вы могли выбрать лучшее решение для данной проблемы.

Я желаю вам найти этот пост полезным.

Ссылка: Использование Groovy — мягкое введение от нашего партнера JCG Алекса Сото в блоге One Jar To Rule All

Статьи по Теме :