Sep. 23rd, 2009

egorius: (Default)

Возвращаясь к Физерсу, работе с унаследованным кодом и тестированию. Допустим, мы осознали, что блочное тестирование рулит, и хотим претворить его в жизнь. Что для этого нужно? Для начала неплохо бы найти что-то наподобие xUnit для языка PL/SQL. Оказывается, есть и такое, например utPLSQL, разработанный небезызвестним Стивеном Фейерштейном.

Дальше мы берём первую попавшуюся функцию, смотрим на неё... И понимаем, что необходимо описать контекст, в котором ведётся разработка.

Есть довольно большая ERP-система, а конкретно — Oracle E-Business Suite (не побоюсь этого слова). Код, который пишется, можно условно поделить на две неравные половины: «отчёты» и «программы». «Отчёты» только читают данные, их отличает минимум логики на уровне PL/SQL, но тяжёлые и сложные SQL-запросы. «Программы» что-то делают с базой; обычно это довольно много PL/SQL-кода и не столь тяжёлые, но всё-таки сложные запросы.

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

Физерс рекомендует нещадно разрывать зависимости от базы, отделяя мухи от котлет, то есть логику от выборки данных. Надо ли этим увлекаться? Не уверен, поскольку так можно погубить наглядность, достигаемую за счёт тесной интеграции SQL с процедурным языком в PL/SQL.

Но, допустим, так или иначе весь не-SQL-код протестирован. Какое тестовое покрытие мы получим? В наших реалиях — небольшое, поскольку, во-первых, «отчётов» всё равно больше, и во-вторых, для «программ» правильная выборка (как и правильное изменение БД) также критически важна. Значит, надо научиться тестировать SQL.

Если функция изменяет состояние БД, это протестировать достаточно просто. Можно запомнить состояние до изменения и сравнить его с состоянием после изменения. Как правило, мы понимаем, как отобразить функциональные требования на состояние таблиц.

А вот с выборками данных, как ни странно, всё гораздо хуже. По идее, если мы хотим протестировать функцию, выбирающую некие объекты с определённым признаком, надо создать в базе объекты, «по построению» как обладающие этим признаком, так и не обладающие им, и проверить, что первые попадают в выборку, а последние — нет. Иными словами, надо подготовить состояние БД для тестирования, создать в базе необходимые тесткейзы.

Проблема в том, что единый с точки зрения функционала объект с точки зрения реализации может быть размазан по десятку-другому разных таблиц. Какие-то объекты можно создавать с помощью API, но какие-то — нет. А аккуратно заполнять все необходимые таблицы — тяжело и ненадёжно, так как связи между таблицами хитрые, а на уровне базы нет никакой проверки целостности. Более того, в некоторых случаях нужно дополнительно запускать ряд программ, совершающих над созданными объектами какие-то действия: можно себе представить, во что выливается, например, имитации закрытия финансового периода!

Понятно, что так или иначе воспроизвести необходимое состояние БД можно, но на практике это задача оказывается на порядок более сложной, чем та программа, которую надо протестировать. Естественно, заниматься этим в здравом уме никто не будет (я пробовал, но это не считается).

Что приходит в голову, так это не создавать новые объекты, а просто найти в БД подходящие из уже существующих — база-то большая. Это проще, но есть три но. Во-первых, какого-нибудь интересного случая может не оказаться, но на нём-то всё и сломается в будущем. Во-вторых, тест может получиться невоспроизводимым, поскольку состояние БД всё время меняется. Во-третьих, кто сказал, что мы сможем правильно найти объект с заданным свойством? Мы ведь, собственно, и собираемся протестировать правильность такой выборки.

Итак, вопрос, на котором я пока застрял: как тестировать запросы? Идеи? Возможно, есть какая-то литература на эту тему?

Profile

egorius: (Default)
egorius

March 2025

M T W T F S S
      1 2
34 567 89
1011 121314 1516
17181920212223
24252627 28 29 30
31      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 13th, 2025 09:55 pm
Powered by Dreamwidth Studios