Размер
Тестирование базы данных. Версия разработчика
Play

Тестирование базы данных. Версия разработчика

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

Стало интересно — как сейчас тестируется логика базы данных. Думаю, неудивительно, что на тот момент поиски в интернете успехом не увенчались. То ли из-за недостаточной настойчивости, то ли из-за желания сделать «такое же, но свое, другое». А имеющиеся варианты не устраивали из-за сложности использования. Например, были и clr-сборки с unit-тестами. Про HP QTP узнал уже позже.

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

Теория

В основу алгоритма вошли принципы:

  • тест состоит из последовательности шагов (простых sql-скриптов)
  • шаг — это единичная операция, принимающая одни данные на вход и возвращающая другие
  • шаги можно объединять в последовательность для создания более сложного модуля
  • меньше кода при создании теста, больше работы мышкой
  • тесты будут храниться в базе
  1. Я хочу 1 раз написать простой скрипт, дать ему название, задать параметры, и сохранить для повторного использования. И пусть программа сама находит параметры из текста скрипта. А я уж задам им тип данных и направление — входной это параметр или выходной.
  2. Хочу объединять несколько скриптов в один компонент. Допустим, нужно положить запись в базу, дождаться её обработки и получить результат этой обработки. Компонент — основная логическая единица для создания теста.
  3. И пусть компоненты можно будет объединять в сам тест. Тот самый, который и будет проверять ту или иную бизнес-операцию.
Что из этого получилось Установка и настройка

Плагин умеет работать с MS SQL Server.

  1. ссылка на плагин к eclipse и исходники в конце статьи. Ставим плагин
  2. создаем пустую базу и выполняем на ней скрипт из репозитория (database\script.sql)
  3. Задаем в настройках 2 базы — для хранения тестов и для выполнения тестов (Window \ Preferences \ Настройки SQL тестов)
Создание проекта

Выбираем настроенные базы и задаем пароли. По завершении жмем «Проверить введенные параметры». Если проверки пройдут успешно, станет доступной кпопка Finish. Жмем её для завершения создания проекта.

По умолчанию нужная view не открывается, делаем это руками: Window -> Show View -> Other -> SQL Test Project Explorer. Созданный проект предстанет в таком виде:

Создание скрипта

Для порядка, через контекстное меню на разделе «Скрипты» создадим папку «Пример», в которой и будут лежать наши примеры. И создадим через контекстное меню на папке «Пример» скрипт «Получить серверное время», который вернет дату и время сервера. Откроем папку «Пример» и, двойным кликом, откроем скрипт. Впишем этот текст скрипта и нажмем кнопку «Найти параметры».

Параметры находятся по сигнатуре :param. А, чтобы получить значение из скрипта, следует вернуть DataSet с названием колонки — именем параметра [:param].

Выберем параметру тип DATE и направление «Выходной». Сохраняем скрипт и ждем рядом кнопку «Выполнить». В колонке «Тестовое значение» отобразится результат:

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

Для решения задачи нам предстоит сделать несколько скриптов, чтобы потом объединить в компонент. Вот эти скрипты:

  1. Задать эталонный интервал в 5 секунд
  2. Получить серверное время #1
  3. Дождаться истечения 5 секунд
  4. Получить серверное время #2
  5. Сравнить времена и убедиться, что разница составляет 5 секунд

(1) может выглядеть совсем просто. Единственный параметр выходной, типа INTEGER:

И (5) так же не сложно. Первые два параметра будут входными, типа DATE. Третий — выходной, типа INTEGER:

Настал черед (3) скрипта, задача которого отработать быстро и сообщить — выполнилось ли условие и можно идти дальше, или повторить его выполнение чуть позже.

Этот скрипт в "ret" вернет единицу, если количество секунд с момента :from по текущий момент не меньше параметра «interval», и ничего не вернет в ином случае. Вот это и будем проверять.

Выбираем тип скрипта «Событие», в выпадающем списке «Параметр» выбираем «ret», и в поле «Значение параметра» впишем 1. Программа будет выполнять скрипт этого типа, пока «ret» не станет равным 1. Повторный запуск будет через 100мс после завершения.

Объединение скриптов в компонент

По аналогии с созданием скриптов, создадим и откроем компонент «Проверить интервал». Перетащим в область «Скрипты» окна компонента мышкой из списка скриптов (в Project Explorer) созданные только что скрипты. Если перенесли что-то лишнее, кликаем мышкой и жмем кнопку «Удалить». У меня получилась такая последовательность скриптов:

  1. Задать эталонный интервал
  2. Получить серверное время
  3. Дождаться завершения таймаута
  4. Получить серверное время
  5. Получить разницу во времени
Параметр С чем связан Получить серверное время NOW [Локальный] start Дождаться завершения таймаута ret пропускаем from [Локальный] start interval [Эталон] interval Получить серверное время NOW [Локальный] finish Получить разницу во времени from [Локальный] start to [Локальный] finish interval [Тест] interval

Перед запуском компонент должен быть сохранен, так как программа перед запуском его подгружает из базы. Нажимаем кнопку «Запустить» в окне компонента. Откроется новое окно с результатом теста, если оно не было открыто ранее.

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

Попробуем «поломать» тест и посмотрим, как это отобразится. Изменим скрипт «Получить разницу во времени» на

Вернем на 1 больше, чем должно быть. Сохраним скрипт и снова запустим компонент.

Открыв детали, при должной сноровке можно даже найти место ошибки:

Не забудем вернуть корректное значение запроса «Получить разницу во времени».

Название Значение Глобальный Глобальная область видимости. Переменная компонента с этим контекстом доступна и вне компонента, в тесте например. При отлаживании компонента, в такой переменной можно задавать значение в колонке «Тестовое значение» таблицы «Параметры» Локальный Локальная переменная. Вне компонента её не видно Тест Тестовое значение. По аналогии с глобальной Эталон Эталонное значение. По аналогии с глобальной Создание теста из компонентов

Тест строится из компонентов точно так же, как и компонент из скриптов. Поэтому не буду подробно его описывать. Сделаем тест «Проверка интервалов» и перетащим в него 2 раза компонент «Проверить интервал». Сохраним и запустим тест.

Заключение

В данной статье описан простейший, искусственный сценарий для теста базы. Но нет ничего сложного и в реальных сценариях, где надо сохранить данные в базу, дождаться их обработки, и получить результат, сравнив с эталоном. Мне было интересно — получится ли убрать рутину ручного труда при создании и выполнении тестов в такой, весьма специфический области. Думаю, отчасти была решена эта задача. И для меня это был опыт знакомства с java и eclipse plugin development. Пусть это и еще один велосипед во всеобщий велопарк.

📎📎📎📎📎📎📎📎📎📎