logo Фёдор Самородов

Как тестировать и отлаживать базы данных

Автоматическое ‎модульное‏ ‎тестирование ‎(unit ‎test) ‎кода ‎приложения‏ ‎— ‎дело‏ ‎простое‏ ‎и ‎понятное. ‎А‏ ‎как ‎тестировать‏ ‎базу ‎данных? ‎Или ‎приложение,‏ ‎которое‏ ‎работает ‎с‏ ‎базой ‎данных.‏ ‎Ведь ‎база ‎— ‎это ‎не‏ ‎просто‏ ‎программный ‎код,‏ ‎база ‎данных‏ ‎— ‎это ‎объект, ‎сохраняющий ‎своё‏ ‎состояние.‏ ‎И‏ ‎если ‎мы‏ ‎начнём ‎в‏ ‎процессе ‎тестирования‏ ‎изменять‏ ‎данные ‎в‏ ‎базе ‎(а ‎без ‎этого ‎какое‏ ‎же ‎у‏ ‎нас‏ ‎будет ‎тестирование?!), ‎то‏ ‎после ‎каждого‏ ‎теста ‎база ‎будет ‎изменяться.‏ ‎Это‏ ‎может ‎помешать‏ ‎последующим ‎тестам‏ ‎и ‎необратимо ‎испортить ‎базу ‎данных.

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

Алгоритм ‎такой:

  1. открываем ‎транзакцию;
  2. если‏ ‎нужно,‏ ‎выполняем ‎подготовительные‏ ‎действия ‎для‏ ‎тестирования;
  3. выполняем ‎модульный ‎тест ‎(или ‎просто‏ ‎запускаем‏ ‎сценарий, ‎работу‏ ‎которого ‎хотим‏ ‎проверить);
  4. проверяем ‎результат ‎работы ‎сценария;
  5. отменяем ‎транзакцию,‏ ‎возвращая‏ ‎базу‏ ‎данных ‎в‏ ‎исходное ‎состояние.

Даже‏ ‎если ‎в‏ ‎тестируемом‏ ‎коде ‎останутся‏ ‎незакрытые ‎транзакции, ‎внешний ‎ROLLBACK ‎всё‏ ‎равно ‎откатит‏ ‎все‏ ‎изменения ‎корректно.

Хорошо, ‎если‏ ‎нам ‎нужно‏ ‎протестировать ‎SQL-сценарий ‎или ‎хранимую‏ ‎процедуру.‏ ‎А ‎если‏ ‎мы ‎тестируем‏ ‎приложение, ‎которое ‎само ‎подключается ‎к‏ ‎базе,‏ ‎открывая ‎новое‏ ‎соединение? ‎Кроме‏ ‎того, ‎если ‎мы ‎занимаемся ‎отладкой,‏ ‎то‏ ‎нам‏ ‎наверняка ‎захочется‏ ‎посмотреть ‎на‏ ‎базу ‎глазами‏ ‎самого‏ ‎отлаживаемого ‎приложения.‏ ‎Как ‎быть ‎в ‎таком ‎случае?

Не‏ ‎торопитесь ‎сочинять‏ ‎распределённые‏ ‎транзакции, ‎есть ‎более‏ ‎простое ‎решение!‏ ‎Штатными ‎средствами ‎SQL-сервера ‎вы‏ ‎можете‏ ‎открыть ‎транзакцию‏ ‎на ‎одном‏ ‎соединении, ‎а ‎продолжить ‎её ‎на‏ ‎другом.

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

Последовательность ‎действий‏ ‎такова:

Начав ‎транзакцию‏ ‎в ‎отладочном ‎сеансе ‎мы ‎должны‏ ‎узнать‏ ‎её‏ ‎идентификатор. ‎Это‏ ‎уникальная ‎строка,‏ ‎по ‎которой‏ ‎сервер‏ ‎различает ‎транзакции.‏ ‎Этот ‎идентификатор ‎надо ‎каким-то ‎образом‏ ‎передать ‎в‏ ‎тестируемое‏ ‎приложение.

Теперь ‎задача ‎приложения‏ ‎— ‎прежде,‏ ‎чем ‎оно ‎начнёт ‎делать‏ ‎то,‏ ‎что ‎ему‏ ‎положено, ‎привязаться‏ ‎к ‎нашей ‎контрольной ‎транзакции.

Затем ‎приложение‏ ‎начинает‏ ‎работать, ‎в‏ ‎том ‎числе‏ ‎запускать ‎свои ‎хранимые ‎процедуры, ‎открывать‏ ‎свои‏ ‎транзакции,‏ ‎менять ‎режим‏ ‎изоляции… ‎Но‏ ‎наш ‎отладочный‏ ‎сеанс‏ ‎всё ‎это‏ ‎время ‎будет ‎находиться ‎внутри ‎той‏ ‎же ‎транзакции,‏ ‎что‏ ‎и ‎приложение.

Допустим, ‎приложение‏ ‎блокирует ‎таблицу‏ ‎и ‎начинает ‎изменять ‎её‏ ‎содержимое.‏ ‎В ‎этот‏ ‎момент ‎никакие‏ ‎другие ‎соединения ‎заглянуть ‎в ‎заблокированную‏ ‎таблицу‏ ‎не ‎могут.‏ ‎Но ‎только‏ ‎не ‎наш ‎отладочный ‎сеанс! ‎Из‏ ‎него‏ ‎мы‏ ‎можем ‎смотреть‏ ‎на ‎базу‏ ‎точно ‎так‏ ‎же,‏ ‎как ‎это‏ ‎делает ‎приложение, ‎так ‎как ‎SQL-сервер‏ ‎считает, ‎что‏ ‎мы‏ ‎находимся ‎в ‎одной‏ ‎транзакции.

В ‎то‏ ‎время ‎как ‎для ‎всех‏ ‎остальных‏ ‎сеансов ‎действия‏ ‎приложения ‎скрыты‏ ‎блокировками…

…наш ‎отладочный ‎сеанс ‎спокойно ‎проходит‏ ‎сквозь‏ ‎блокировки ‎(сервер‏ ‎думает, ‎что‏ ‎это ‎наши ‎собственные ‎блокировки)!

Или ‎представьте,‏ ‎что‏ ‎приложение‏ ‎начинает ‎работать‏ ‎со ‎своими‏ ‎версиями ‎строк‏ ‎в‏ ‎режиме ‎SNAPSHOT.‏ ‎Как ‎заглянуть ‎в ‎эти ‎версии?‏ ‎Даже ‎это‏ ‎возможно,‏ ‎если ‎вы ‎связаны‏ ‎общей ‎транзакцией!

Не‏ ‎забудьте ‎в ‎конце ‎этого‏ ‎увлекательного‏ ‎процесса ‎откатить‏ ‎контрольную ‎транзакцию.‏ ‎Это ‎можно ‎сделать ‎как ‎из‏ ‎отладочного‏ ‎сеанса ‎(если‏ ‎процесс ‎тестирования‏ ‎завершится ‎нормально), ‎так ‎и ‎из‏ ‎самого‏ ‎приложения‏ ‎(если ‎в‏ ‎нём ‎случится‏ ‎что-то ‎непредвиденное).

Предыдущий Следующий
Все посты проекта
0 комментариев

Подарить подписку

Будет создан код, который позволит адресату получить бесплатный для него доступ на определённый уровень подписки.

Оплата за этого пользователя будет списываться с вашей карты вплоть до отмены подписки. Код может быть показан на экране или отправлен по почте вместе с инструкцией.

Будет создан код, который позволит адресату получить сумму на баланс.

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

Добавить карту
0/2048