Реализация мониторинга и интеграционного тестирования информационной системы с использованием Scalatest

image

В данной статье хочу поделиться опытом создания тестов с использованием фреймворка «Scalatest» для автоматизации тестирования. Статья будет состоять из 2х частей. Первая — пошаговая инструкция для создания и запуска базового теста, вторая — рассмотрение более сложных случаев и нюансов тестового стека, информация по созданию тестовых отчетов, решение возникающих проблем.

Существует множество решений для автоматизации тестирования. Каждое их них имеет свои особенности, преимущества, недостатки, различаются порогом вхождения, удобством применения, эффективностью, универсальность, кругом задач, для которых хорошо подходит. Для задачи автоматизации интеграционного тестирования и мониторинга систем для одного из проектов удачным решением оказалось применение связки «Scala» + «ScalaTest» + «SBT»
Задача:

Автоматизировать интеграционное тестирование;
Организовать мониторинг — автоматизированную проверку работоспособности/доступности информационной системы в целом и ее отдельных частей.
Обеспечить быструю локализацию проблемного компонента в случае отказа системы;
Предоставить отчет о выполнении теста в понятной форме.

Общий замысел таков: Выполняется некое действие, которое инициирует начало обработки в информационной системе (отправка сообщения сервису, менеджеру очередей, выполнение на веб-интерфейсе определенной последовательности действий). Система обрабатывает сообщение, прогоняя его через свои компоненты, подсистемы. Мы проверяем, что подсистема выполнила свою задачу по неким признакам: наличие записи в логе, наличие новой записи в БД, корректные ответы на запросы, получение ответных сообщений от системы, отображение на сайте. Каждая такая проверка оборачивается в шаг тестового сценария, который либо может быть успешен, либо провален.

После прохождения теста формируется отчет, к которому прикрепляются некоторые файлы (Ответы системы, скриншоты, результаты выполнения запросов), из которого можно определить, все ли хорошо в системе и где проблема. Примеры отчета представлены ниже:

image

image

image

image

Краткое описание используемых технологий:

Scala — язык программирования, спроектированный кратким и типобезопасным для простого и быстрого создания компонентного программного обеспечения, сочетающий возможности функционального и объектно-ориентированного программирования. Работает поверх jvm.
Sbt — (scala build tool) — система автоматической сборки для проектов, написанных на языках Scala и Java.
Scalatest — фреймворк для тестирования приложений. На главной странице читаем «simply productive» и «scalatest is designed to increase your team's productivity through simple, clear tests and executable specifications that improve both code and communications».
Selenium WebDriver — инструмент для тестирования web-приложений, набор средств для управления браузером, эмуляции пользовательских действий.

Этот стек порадовал универсальностью (разработка и запуск на win/linux/macos особенно не отличаются), богатством возможностей (если не получается реализовать что-то с помощью scala, можем использовать немного модифицированный java код и java библиотеки), эффективностью, поддержкой со стороны IDE (IntelliJ IDEA, Eclipse), хорошей документацией. Особенно порадовало, что это “Просто работает”, (если опустить проблемы с кодировкой в Windows), то есть количество проблем, решаемых бубном, не так велико, да и для начала работы со стеком необязательно иметь большой опыт в программировании и настройке информационных систем. Писать на Scala довольно приятно, особенно если использовать хорошую IDE.

На машине должна быть установлена Oracle JDK, желательно 8-й версии (1.8), на предыдущих версиях некоторые компоненты могут не завестись, на openJDK не будет работать Idea. www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html,

Для разработки теста будем использовать IntelliJ IDEA Community Edition от jetbrains.

Для этого ставим idea, запускаем, ставим плагин scala.

image

6d5afec15e6e4089a4db7d57c0e9cb28.jpg

image

Перезапускаем приложение.

image

Создаем новый проект, Scala -> SBT.

image

Вводим имя, директорию, выбираем путь до JDK, ставим галку «Use auto-import», чтобы изменения в файле build.sbt сразу же актуализировались.

image

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

image

Файл “build.sbt”, который создался в директории проекта, содержит информацию о проекте, а также список используемых компонентов.
Для подключения фреймворка “scalatest” добавим в “build.sbt” соответствующую строку. — libraryDependencies += «org.scalatest» % «scalatest_2.11» % «3.0.0-M7». Это последняя на момент написания статьи версия.

(SBT использует MAVEN репозиторий, поэтому найти библиотеку можно на сайте, к примеру, mvnrepository.com/artifact/org.scalatest/scalatest_2.11/3.0.0-M7).

(В SBT есть возможность подгружать автоматом последнюю версию, указав «latest.integration» в поле с версией. Но, это может грозить проблемами — изменением поведения при обновлении. Лучше фиксировать версию).

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

image

Индикатор в нижней части формы показывает готовность проекта. Создадим простой тест, посмотрим, как работает скалатест. Тестовые классы создаются в директории /src/test/scala из контекстного меню.

image

Назовем его «DummyTest». Текст класса:

/**
 * Created by user on 26.08.2015.
 */
 
import org.scalatest.{Matchers, FreeSpec}
 
class DummyTest extends FreeSpec with Matchers{
 
  "Два плюс три равно пяти" in {
    val num = 2+3
    num should be (5)
  }
 
  "Два плюс три равно четырем" in {
    val num = 2+3
    num should be (4)
  }
}


Опишем тест. Из представленных здесь стилей мне по душе «FreeSpec». Его и будем использовать (добавляем «extends FreeSpec» после имени класса). «With Matchers» нужен для использования сравнений, к примеру, x should be (y) проверяет, что значение x совпадает со значением y. Более подробно сравнение значений здесь и здесь.

Тест содержит 2 шага. Первый — заведомо правильный, второй должен упасть. Шаг имеет название «Два плюс три равно пяти», которое отображается в отчетах. Это строка, которая заключена в кавычки, в ней допускается использование кириллицы. Слово in разделяет название шага и тело, заключенное в скобки "{","}". Тест считается пройдённым, если все шаги в теле прошли успешно. Тест считается заваленным, если что-то пошло не так и тест упал на шаге.

«val num = 2+3» — объявляем переменную и присваиваем ей значение.

В общем случае объявление в scala выглядит так:

val or val VariableName [: DataType] = Initial Value

val — значение, которое не меняется(похоже на константу), var — переменная — меняется в ходе выполнения кода. Использование val предпочтительнее. «num should be (5)» — сравнивает значения, проверяет, что значение переменной «num» равно пяти.

Если в строке с импортом отображается ошибка, то, вероятно, нужные библиотеки еще не загрузились, и идея не может импортировать нужные компоненты.

Выполним сценарий в Idea. Вызываем контекстное меню внутри класса — в нем появляется пункт «Run» (Запускать можно не любой класс, такую возможность предоставляет нам «extends FreeSpec» — использование trait FreeSpec). После этого класс добавится в список в правой верхней части экрана, там его можно запустить кнопкой, или сочетанием клавиш «Shift + f10»

image

Если работаем в windows — появится ошибка — проблема с кодировкой. 1251 — дефолтная виндовая кодировка не работает с кириллицей. Поэтому меняем на UTF-8 в правой нижней части окна. В диалоговом окне нажимаем «Convert». В linux/mac — проблемы быть не должно, utf-8 – кодировка по умолчанию для новых файлов в Idea.

image

Еще раз запускаем тест, смотрим результат в нижней части формы.

image

Видим некое дерево с проверками слева, описание ошибки в середине и результат справа. Ожидаемо второй шаг упал.

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

Для начала, поставим SBT, версии не ниже 0.13.8. Не рекомендуется ставить sbt из репозитория linux, потому что он там либо отсутствует, либо версия может быть устаревшей.

После установки sbt проверим версию, выполнив команду "sbt --version".

Так как в параметрах запуска sbt прописаны параметры «MaxPermSize», а в восьмой java он не нужен, то выпадет соответствующее предупреждение. Можем проигнорировать его или поменять настройки SBT в конфигурационных файлах. Версия “0.13.8” нас вполне устроит. Переходим в директорию SBT проекта. В ней выполняем команду для запуска тестов — «sbt test». Тест пройдет, прошедший шаг будет зеленым, зафейленный — красным.

image

Для стандартной консоли windows опять существует проблема кодировки. Чтобы отображать красиво русский текст, необходимо изменить кодировку страницы и шрифты. В свойствах окна командной строки ставим «Lucida Console».

image

В окне пишем команду «chcp 1251». После этого повторно выполняем «sbt test» еще раз — все должно отображаться красиво.

image

Также корректного отображения русских символов можно добиться, изменив конфигурационные файлы SBT. Базовая заготовка для теста готова.

Рассмотрим пример для проверки работоспособности сайта. Тест будет проверять, что возвращается страница и содержимое тега «title» правильное.
Проверим 2-мя способами — Get-запрос и selenium сценарий. Для реализации теста с использованием web-driver нужен “Firefox” (в принципе возможно использование других браузеров, в том числе «HtmlUnit», которому не нужен графический интерфейс, но с огнелисом проблем, как правило, меньше, да и в поставке многих линукс дистрибутивов он присутствует по умолчанию).

Для выполнения сценария Selenium, добавим в “build.sbt” строку libraryDependencies += "org.seleniumhq.selenium" % "selenium-java" % "2.46.0". Идея начнет подтягивать из репозитория компоненты для работы Селениума.

Создадим класс, назовем его, к примеру, “GetTest”. Импортируем нужные библиотеки и в начале класса определим метод “get” для получения текста страницы и создадим экземпляр «FirefoxDriver».

import org.openqa.selenium.WebDriver
import org.openqa.selenium.firefox.FirefoxDriver
import org.scalatest.selenium.WebBrowser
import org.scalatest.{Matchers, FreeSpec}
import scala.io.Source
 
class GetTest extends FreeSpec with Matchers with WebBrowser{
 
  val pageURL = "http://scalatest.org/about"
  def get(url: String) = Source.fromURL(url, "UTF-8").mkString
  implicit val webDriver: WebDriver = new FirefoxDriver()
 
 
  "Get запрос страницы %s и проверка заголовка".format(pageURL) in
    {
      get(pageURL) should include("<title>ScalaTest</title>")
    }
 
  "Открытие страницы " + pageURL+ " и проверка заголовка"  in
    {
      go to pageURL
      pageTitle should be ("ScalaTest")
      quit()
    }
}


Метод get получает код страницы от веб-сервера и преобразует в строку, в которой потом проверяется наличие подстроки "ScalaTest".

Второй тест открывает в огнелисе страницу и сверяет ее заголовок с шаблоном. Так как название шага — строка, то в нее можно добавлять переменные, склеивая строку, либо с использованием команды format. Правой кнопкой кликаем в классе — запускаем. Результат наблюдаем в нижней части формы.

image

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

Примеры действий, которые можно выполнять в тестах:

• GET/POST запрос. Проверка содержимого ответа;
• Запрос к базе данных. Проверка содержимого ответа;
• Генерация сообщений и их отправка в очередь;
• Получение сообщений из очереди. Проверка содержимого ответа;
• Проверка веб-интерфейса (Корректность работы, отображение значений на форме, получение скриншотов);
• Запуск сценариев командной строки (к примеру, мониторинг оставшейся памяти, пространства на жестком диске).

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

Вопросы, которые будут рассмотрены в следующей статье:

• Генерация отчетов;
• Подключение конфигурационного файла;
• Параллельный запуск тестов;
• Запросы к БД;
• Работа с менеджером очередей;
• Более сложные сценарии с использованием Selenium WebDriver;
• Выполнение команд системы;
• Работа со временем (Паузы, ожидание, ограничение времени выполнения);
• Еще некоторые особенности работы стека.

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

© Habrahabr.ru