Эффективное тестирование приложений БД

Tiny
Дата: 22.03.2011 11:44:09
Доброго времени суток!

Извините, если баян, но поиск по сабжевой теме целостной картины не дал, потому спрашиваю.

Есть система, вся бизнес-логика которой написана на PL/SQL. Система представляет собой биллинг, т.е. основная часть её функционала - это расчетные алгоритмы, которые выполняются относительно долго на большом объёме данных, и имеют в своём составе большое количество операций записи.

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

Что есть на настоящий момент:

1. "Тесты" для каждого расчетного алгоритма, которые, по факту, представляют собой простые SQL-запросы на проверку возникновения разных некорректных ситуаций (допустим, когда долг по клиенту не совпадает с суммой всех долгов по каждой из услуг клиента и т.п.). Т.е. эти проверки ориентированы не на проверку на конкретных объектах (клиентах, счетах с определенным ID и т.п.), а на всём объёме данных. Вроде нормально - написал запрос, и выполнил после прогона алгоритма.


2. Unit-тесты для некоторых особенных случаев (например, когда берём объект, который считается по некоему "нетиповому" правилу, и сравниваем результат расчета по нему с конкретным числом). Когда unit - это процедура/функция, которая ничего не пишет в базу/не читает из базы (или читает только некие условно-постоянные данные - справочники и т.п.) - всё замечательно.
К тому же, есть для этого и средства соответствующие - тот же utPLSQL, например.

Но. Если вдруг возникает желание написать unit-тест на такую поцедуру/функцию, которая интенсивно и много читает из базы и пишет в базу - возникает некое неудобство, а именно: для каждого такого теста надо где-то хранить большой объём тестовых входных и выходных данных, чтобы при запуске теста можно было подменить реальные данные тестовыми из нужного места хранения, а потом - сравнить полученный результат с сохраненными тестовыми выходными данными.

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

3. Тестирование производительности - обычный прогон алгоритмов на полном объёме данных с последующим анализом длительности выполнения каждого из операторов (в профайлере или при помощи Top Sql в Enterprise Manager)

Что имеем.

Первый способ (проверочные скрипты на всём объёме) хорош, но имеет смысл только тогда, когда сами скрипты - достаточно простые и отлавливают достаточно "грубые" ошибки - в противном случае набор скриптов будет полностью повторять всю логику системы, в чём нет смысла.

Второй способ - хорош только до тех пор, пока не встаёт вопрос о создании большого количества юнит-тестов для процедур, интенсивно и в больших объёмах читающих и изменяющих данные.

Вопрос - как быть в таком случае? Может, уже все всё знают и у всех всё хорошо в этом вопросе, а я сижу и пытаюсь придумать, как велосипед изобрести?
Kerk
Дата: 02.04.2011 00:36:13
Взгляните на Code Tester for Oracle, коммерческое продолжение utPLSQL

http://www.quest.com/code-tester-for-oracle/
http://unittest.inside.quest.com/index.jspa