Есть следующие мысли касательно сабжа. Просьба указать на недостатки
Постановка задачи:
Есть корпоративная база данных. Предназначена для ввода в нее каких-то данных, их хранении и последующей обработке. Например, расчет зарплаты, учет каких-либо заказов итд.
База данных достаточно сложная (то есть один человек не в состоянии держать в голове все взаимосвязи и помнить, какая процедура откуда вызывается) и постоянно модифицируется. Стоит задача при вносе любых новых изменений не совершать подвигов по отладке внезапно переставших работать процедур, а спокойно их делать, не боясь, что придется из своего кармана компенсировать ошибки в расчете
Путь решения
Мне на данный момент видется только один выход — тестирование работоспособности базы данных.
делать это можно несколькими способами:
1) Можно завести штат тестеров и заставить их выполнять эту работу.
Но: тестеры не помогут с отладкой (если сразу видно, что есть ошибки, но совершенно непонятно, откуда они). Кроме того, если рассматривать БД, которая делается "под себя" отделом АСУ, то тестеров там как правило нет.
2) Использовать функциональное тестирование БД. То есть тестировать крупные функциональные модули. Например, тест процедуры расчета зарплаты сотрудников. Или тест расчет общей наработки в часах по всем машинам в автохозяйстве, итд. Какие проблемы здесь — нужно очень много тестовых данных и тесты сами получаются очень сложными. Этот вопрос уже здесь рассматривался, и похоже, решения не нашел.
3) Использовать модульное( UNIT) тестирование БД. Предлагаю рассмотреть этот вопрос более подробно.
Что такое unit — тестирование?
Unit тестирование (или модульное тестирование) ставит своей целью проверить каждый модуль (unit) программы на работоспособность.
Для того, чтобы эффективно применять модульное тестирование, необходимо, чтобы размер каждого модуля, подвергаемого тестированию, был минимален. Только в этом случее написание теста становится достаточно простым. То есть если БД имееет дизайн, не подходящий для модульного тестирования, тесты скорее всего потребуют большого количества исходных данных и проверок, что приведет к большой сложности разработываемых тестов.
Соответственно задача тестирования БД в первую очередь заключается в разработке такой структуры БД, которую удобно тестировать
Приведу пример из своей области, но могу то же самое проделать с другой
(если скажете, что в вашей области это неприменимо)
Есть такси. есть водители, которые получают и выполняют заказы. С каждого заказа водитель должен сдать какую-то сумму денег. Сумма меняется в зависимости от типа заказа, продолжительности, стоимости, доп условий итд. Необходимо вести учет денег, сдаваемых водителями.
Как это может быть реализовано.
Есть таблицы — архив заказов, архив платежей водиетей, сальдовая таблица. Есть встроенная процедура "рассчитать текущий баланс водителя". Что она делает: суммирует суммы сдачи за кажый заказ начиная с даты последнего сальдо (предположим, что сумму сдачи за заказ считает другая процедура в другом месте) и вычитает из полученного сумму всех его платежей тоже начиния с даты сальдо.
Так вот, тестированию такая структура поддается плохо — потому что надо подготовить большое количество данных (забить тестовые заказы и платежи), и написать тест, который учтет все возможные варианты. В более сложных случаях это может быть и практически невозможно.
Но: описанная структура является на самом деле не
модульным тестированием, а фукнциональным, несмотря на то, что тестируется вроде бы отдельный маленький модуль всей БД. Кроме того, написание теста для такой процедуры — это на 80% проверка умения SQL сервера выполнять SQL запросы — выбирать и агрегировать данные, что протестировано до нас и точно работает
Следовательно, нужно разбивать данную процедуру на более мелкие и тестировать уже их (сразу оговорюсь, проблемы с производительностью я не рассматриваю).
Например:
Для каждой операции, влекущей начисление (снятие) денег со счета водителя вводится понятие транзакции. Придется для каждого типа заказа и варианта расчета его стоимости придумать свой тип транзакции, который будет считать стоимость только своего заказа. При попадании в базу нового заказа в таблицу "журнал транзакций" будет делаться запись с типом транзакции, кодом водителя и всеми параметрами, влияющими на сумму сдачи. Аналогично при вносе водителем денег будет создаваться транзакция со свомм типом и параметрами.
Процедура расчета баланса просто сделает селект по всем строкам с датой больше сальдо и просуммирует суммы (извините за тавтологию) транзакций (считать их можно через user functions, параметрами которых будут уже физические величины, а не ссылки на строки)) и сгруппирует их по водителям.
В данной структуре саму процедуру расчета тестировать не надо, так как любые изменения процедуры расчета будут касаться только транзакций, а уверенность в том, что она суммирует правильно обеспечивается SQL сервером Кроме того, такая структура удовлетворяет принципу OCP — закрытость для изменений и открытость для расширений, что хорошо само по себе даже без тестирования
Тестировать надо будет только процедуру (триггер), выбирающий нужный тип транзакции в зависимости от заказа(здесть нужна одна тестовая строка данных) и сами транзакции (здесть только параметры и возвращаемое значение). Все!
Вот в общем вся идея. Если БД не поддается тестированию — значит что-то сделано не так.
Буду признателен за примеры, которые не укладываются в данную схему.
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, kolam, Вы писали:
K>Здравствуйте, Sshur, Вы писали:
S>>All, оставь хотя бы несколько комментариев. K>Э тебе в ближайший вторник подробно изложу свою точку зрения
Давай, давай, только конструктивно
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
...
S>3) Использовать модульное( UNIT) тестирование БД. Предлагаю рассмотреть этот вопрос более подробно.
А что такое "модульное( UNIT) тестирование БД"? Это тестирование хранимых процедур, функций и другой логики, которая работает на стороне сервера SQL? Или Вы подразумеваете под этим понятием прогон действий в своей программе и проверка результата в БД?
В обоих случаях подразумевается перед каждым тестом создание тестового набора данных, прогон теста в программе и сравнение с заранее подготовленным эталонным результатом того результата, который получился. При этом необходимо учитывать, что не все тесты могут выполняться последовательно без промежуточной нормализации данных БД для обеспечения независимости (или зависимости) проводимых тестов. При этом в процессе тестирования или промышленной эксплуатации набор тестов имеет свойство расширяться для более полного тестового покрытия.
Здесь действует обычный принцип unit-тестирования.
S>Для того, чтобы эффективно применять модульное тестирование, необходимо, чтобы размер каждого модуля, подвергаемого тестированию, был минимален. Только в этом случее написание теста становится достаточно простым. То есть если БД имееет дизайн, не подходящий для модульного тестирования, тесты скорее всего потребуют большого количества исходных данных и проверок, что приведет к большой сложности разработываемых тестов.
S>Соответственно задача тестирования БД в первую очередь заключается в разработке такой структуры БД, которую удобно тестировать
Совсем не согласен, т.к. главная задача разработчика БД — это оптимальная производительность, а не удобство тестирования. Если "БД имееет дизайн, не подходящий для модульного тестирования", то необходимо пересмотреть свои взгляды на "модульное тестирование".
...
S>Следовательно, нужно разбивать данную процедуру на более мелкие и тестировать уже их (сразу оговорюсь, проблемы с производительностью я не рассматриваю). S>Например: S>Для каждой операции, влекущей начисление (снятие) денег со счета водителя вводится понятие транзакции. Придется для каждого типа заказа и варианта расчета его стоимости придумать свой тип транзакции, который будет считать стоимость только своего заказа. При попадании в базу нового заказа в таблицу "журнал транзакций" будет делаться запись с типом транзакции, кодом водителя и всеми параметрами, влияющими на сумму сдачи. Аналогично при вносе водителем денег будет создаваться транзакция со свомм типом и параметрами. S>Процедура расчета баланса просто сделает селект по всем строкам с датой больше сальдо и просуммирует суммы (извините за тавтологию) транзакций (считать их можно через user functions, параметрами которых будут уже физические величины, а не ссылки на строки)) и сгруппирует их по водителям. S>В данной структуре саму процедуру расчета тестировать не надо, так как любые изменения процедуры расчета будут касаться только транзакций, а уверенность в том, что она суммирует правильно обеспечивается SQL сервером Кроме того, такая структура удовлетворяет принципу OCP — закрытость для изменений и открытость для расширений, что хорошо само по себе даже без тестирования S>Тестировать надо будет только процедуру (триггер), выбирающий нужный тип транзакции в зависимости от заказа(здесть нужна одна тестовая строка данных) и сами транзакции (здесть только параметры и возвращаемое значение). Все!
Бррр. Ничего не понял, но, судя по всему, речь идет о некоторой автоматизации сохранения промежуточных данных. Как это относится к unit-тестированию я понять не могу.
Здравствуйте, stasukas, Вы писали:
S>>Соответственно задача тестирования БД в первую очередь заключается в разработке такой структуры БД, которую удобно тестировать S>Совсем не согласен, т.к. главная задача разработчика БД — это оптимальная производительность, а не удобство тестирования. Если "БД имееет дизайн, не подходящий для модульного тестирования", то необходимо пересмотреть свои взгляды на "модульное тестирование".
А вот здесь начинается магия. Ведь можно же сочетать и то и другое... но очень редко получается
Здравствуйте, stasukas, Вы писали:
S>Здравствуйте, Sshur, Вы писали:
S>...
S>>3) Использовать модульное( UNIT) тестирование БД. Предлагаю рассмотреть этот вопрос более подробно. S>А что такое "модульное( UNIT) тестирование БД"? Это тестирование хранимых процедур, функций и другой логики, которая работает на стороне сервера SQL? Или Вы подразумеваете под этим понятием прогон действий в своей программе и
проверка результата в БД?
тестирование хотя бы встроенных процедур. А вообще — всего что есть в БД, вплоть до структуры таблиц.
S>В обоих случаях подразумевается перед каждым тестом создание тестового набора данных, прогон теста в программе и сравнение с заранее подготовленным эталонным результатом того результата, который получился. При этом необходимо учитывать, что не все тесты могут выполняться последовательно без промежуточной нормализации данных БД для обеспечения независимости (или зависимости) проводимых тестов. При этом в процессе тестирования или промышленной эксплуатации набор тестов имеет свойство расширяться для более полного тестового покрытия.
S>Здесь действует обычный принцип unit-тестирования.
Это понятно, но когда тестируешь объекты в программе, для них не нужно многомегабайтных данных. Насчет неудобств при тестировании отчета, который требует для себя кучи исходных данных, говорилось уже много.
Смысл именно в том, чтобы не отходить от сущности unit-тестирования и обойтись без исходных данных.
S>>Соответственно задача тестирования БД в первую очередь заключается в разработке такой структуры БД, которую удобно тестировать S>Совсем не согласен, т.к. главная задача разработчика БД — это оптимальная производительность, а не удобство тестирования. Если "БД имееет дизайн, не подходящий для модульного тестирования", то необходимо пересмотреть свои взгляды на "модульное тестирование".
Ну это уже компромисс.. того что нужно в каждом конкретном случае. Я в своей области готов пожертвовать производительностью, чтобы постоянно быть полностью уверенным в работоспособности всех моих баз. Просто задача стоит поддерживать неограниченное количество схожих, но отличающихся в деталях баз. И чтобы стоимость внесения изменений не вызывала шок у заказчика
.
SS>>Тестировать надо будет только процедуру (триггер), выбирающий нужный тип транзакции в зависимости от заказа(здесть нужна одна тестовая строка данных) и сами транзакции (здесть только параметры и возвращаемое значение). Все!
S>Бррр. Ничего не понял, но, судя по всему, речь идет о некоторой автоматизации сохранения промежуточных данных. Как это относится к unit-тестированию я понять не могу.
ой.. речь идет о том, что для тестирования такой структуры не нужны те самые многомегабайтные исходные данные.
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[3]: unit тестирование баз данных
От:
Аноним
Дата:
10.03.05 08:14
Оценка:
Здравствуйте, Sshur, Вы писали:
S>ой.. речь идет о том, что для тестирования такой структуры не нужны те самые многомегабайтные исходные данные.
А чем плохо тестирование на многомегабайтных исходных данных?
Заодно и эффективность потестируешь.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Sshur, Вы писали:
S>>ой.. речь идет о том, что для тестирования такой структуры не нужны те самые многомегабайтные исходные данные.
А>А чем плохо тестирование на многомегабайтных исходных данных? А>Заодно и эффективность потестируешь.
Плохо тем, что такой тест писать сложно, а если их много — то надо сначала данные залить, потом запускать тест, потом сравнивать результаты с эталонными. Это долго, кроме того, требуется специальная тестовая база, что влечет геморрой с синхронизацией изменений итд. Вот я и хочу за счет усложнения структуры обойтись без них. Нужно тестировать не весь отчет сразу, а отдельные бизнес-правила, по которым (например) производятся начисления.
А для того, чтобы их можно было тестировать, их нужно вынести в отельные процедуры (или функции).
Но это все конечно по месту, если производительность критична или нет большого количества изменений, то смысла это внедрять нет..
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, Sshur, Вы писали:
S>>>3) Использовать модульное( UNIT) тестирование БД. Предлагаю рассмотреть этот вопрос более подробно. S>>А что такое "модульное( UNIT) тестирование БД"? Это тестирование хранимых процедур, функций и другой логики, которая работает на стороне сервера SQL? Или Вы подразумеваете под этим понятием прогон действий в своей программе и S>>проверка результата в БД?
S>тестирование хотя бы встроенных процедур. А вообще — всего что есть в БД, вплоть до структуры таблиц.
S>>В обоих случаях подразумевается перед каждым тестом создание тестового набора данных, прогон теста в программе и сравнение с заранее подготовленным эталонным результатом того результата, который получился. При этом необходимо учитывать, что не все тесты могут выполняться последовательно без промежуточной нормализации данных БД для обеспечения независимости (или зависимости) проводимых тестов. При этом в процессе тестирования или промышленной эксплуатации набор тестов имеет свойство расширяться для более полного тестового покрытия.
S>>Здесь действует обычный принцип unit-тестирования.
S>Это понятно, но когда тестируешь объекты в программе, для них не нужно многомегабайтных данных.
Кто сказал, что не нужно? В любом случае необходимо подготовить наборы данных для проверки правильности, неправильности и некоторых околограничных условий.
S>Насчет неудобств при тестировании отчета, который требует для себя кучи исходных данных, говорилось уже много. S>Смысл именно в том, чтобы не отходить от сущности unit-тестирования и обойтись без исходных данных.
В unit-тестировании исходные данные всегда нужны. А Ваш случай более похож на оперативную проверку в процессе эксплуатации. Да, это можно делать, но на этапе внедрения. В оперативной работе этого не требуется, т.к. вся работа системы в целом должна описываться unit-тестами с добавлением всех новых нестандартных ситуаций в поведении системы (багов) с момента их исправления. Таким обраом, система тестов будет постепенно разрастаться, но только за счет добавления нового и, в основном, без модификации старого.
S>>>Соответственно задача тестирования БД в первую очередь заключается в разработке такой структуры БД, которую удобно тестировать S>>Совсем не согласен, т.к. главная задача разработчика БД — это оптимальная производительность, а не удобство тестирования. Если "БД имееет дизайн, не подходящий для модульного тестирования", то необходимо пересмотреть свои взгляды на "модульное тестирование".
S>Ну это уже компромисс.. того что нужно в каждом конкретном случае. Я в своей области готов пожертвовать производительностью, чтобы постоянно быть полностью уверенным в работоспособности всех моих баз. Просто задача стоит поддерживать неограниченное количество схожих, но отличающихся в деталях баз. И чтобы стоимость внесения изменений не вызывала шок у заказчика
Думаю, что здесь кроется ошибка проектирования, т.к. в данном случае общие части должны быть вынесены отдельно от специфичных, а система тестирования по ним будет единой. Специфичные свойства системы могут совершенно спокойно расширять основные свойства системы. Для специфичных свойств каждой системы пишется свой набор таких же специфичных тестов. Вот такая комбинация и позволяет полностью охватить все системы тестами.
SS>>>Тестировать надо будет только процедуру (триггер), выбирающий нужный тип транзакции в зависимости от заказа(здесть нужна одна тестовая строка данных) и сами транзакции (здесть только параметры и возвращаемое значение). Все!
S>>Бррр. Ничего не понял, но, судя по всему, речь идет о некоторой автоматизации сохранения промежуточных данных. Как это относится к unit-тестированию я понять не могу.
S>ой.. речь идет о том, что для тестирования такой структуры не нужны те самые многомегабайтные исходные данные.
Так речь идет о промежуточной агрегации данных?
Здравствуйте, Sshur, Вы писали:
S>>>ой.. речь идет о том, что для тестирования такой структуры не нужны те самые многомегабайтные исходные данные.
А>>А чем плохо тестирование на многомегабайтных исходных данных? А>>Заодно и эффективность потестируешь.
S>Плохо тем, что такой тест писать сложно, а если их много — то надо сначала данные залить, потом запускать тест, потом сравнивать результаты с эталонными. Это долго, кроме того, требуется специальная тестовая база, что влечет геморрой с синхронизацией изменений итд. Вот я и хочу за счет усложнения структуры обойтись без них. Нужно тестировать не весь отчет сразу, а отдельные бизнес-правила, по которым (например) производятся начисления.
Не вижу тогда особого смысла в таком тестировании, т.к. нормального покрытия тестами все-равно не будет, а создание такого специфичного тестирования будет сравнима с трудозатратами на стандартное unit-тестирование. Если сохранять версионность структуры данных, тестов и кода, то, при использовании некоторых автоматизирующих средств сборки и проверки проектов, можно получать после изменения любого проекта места, влияющие на работу той или иной части проекта (-ов). Ну а поставить на ночь сборку и тестирование всех связанных проектов, а на утро получить результаты — хорошая практика при разработке сложных или сильно взаимосвязанных проектов.
S>А для того, чтобы их можно было тестировать, их нужно вынести в отельные процедуры (или функции).
Кто мешает подготовить небольшие наборы достаточно типичных (и/или не типичных) данных для проверки стандатрным способом тех же самых процедур и функций?
S>Но это все конечно по месту, если производительность критична или нет большого количества изменений, то смысла это внедрять нет..
S>>тестирование хотя бы встроенных процедур. А вообще — всего что есть в БД, вплоть до структуры таблиц. S>
Ничего смешного. Есть 10 баз, отданных заказчикам,каждая из которых модифицировалась под конкретные условия. Таблицы могут отличаться по структуре.
Потом берем и вводим новую функциональность в программу (и соответственно меняем базу). И вот нужно убедиться что та версия клиентского ПО, скомпилированная под конкретного заказчика, будет работать с новой базой. И случайное изменение структуры таблицы (например, программист подумал и решил, что данное поле теперь будет not null. А у заказчика возможен вариант с null в данных) может привести к неработоспособности базы.
Так что тут либо отказываться от поддержки, либо вводить тестирование всего что движеться
S>>Насчет неудобств при тестировании отчета, который требует для себя кучи исходных данных, говорилось уже много. S>>Смысл именно в том, чтобы не отходить от сущности unit-тестирования и обойтись без исходных данных. S>В unit-тестировании исходные данные всегда нужны. А Ваш случай более похож на оперативную проверку в процессе эксплуатации. Да, это можно делать, но на этапе внедрения. В оперативной работе этого не требуется, т.к. вся работа системы в целом должна описываться unit-тестами с добавлением всех новых нестандартных ситуаций в поведении системы (багов) с момента их исправления. Таким обраом, система тестов будет постепенно разрастаться, но только за счет
добавления нового и, в основном, без модификации старого.
Исходные данные в виде заполненной таблицы с миллионом строк, вот что я имею ввиду. А исходые данные в виде параметров функции несомненно нужны.
S>>>>Соответственно задача тестирования БД в первую очередь заключается в разработке такой структуры БД, которую удобно тестировать S>>>Совсем не согласен, т.к. главная задача разработчика БД — это оптимальная производительность, а не удобство тестирования. Если "БД имееет дизайн, не подходящий для модульного тестирования", то необходимо пересмотреть свои взгляды на "модульное тестирование".
S>>Ну это уже компромисс.. того что нужно в каждом конкретном случае. Я в своей области готов пожертвовать производительностью, чтобы постоянно быть полностью уверенным в работоспособности всех моих баз. Просто задача стоит поддерживать неограниченное количество схожих, но отличающихся в деталях баз. И чтобы стоимость внесения изменений не вызывала шок у заказчика S>Думаю, что здесь кроется ошибка проектирования, т.к. в данном случае общие части должны быть вынесены отдельно от специфичных, а система тестирования по ним будет единой. Специфичные свойства системы могут совершенно спокойно расширять основные свойства системы. Для специфичных свойств каждой системы пишется свой набор таких же специфичных тестов. Вот такая комбинация и позволяет полностью охватить все системы тестами.
Это так и есть, проблема мною сформулирована выше. Могут изменяться и общие части, и какова взаимосвязь общих и специфичных частей уже никто не знает ввиду общей сложности системы.
S>>ой.. речь идет о том, что для тестирования такой структуры не нужны те самые многомегабайтные исходные данные. S>Так речь идет о промежуточной агрегации данных?
Можно и так сказать. Наверно
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, stasukas, Вы писали:
S>Здравствуйте, Sshur, Вы писали:
S>>>>ой.. речь идет о том, что для тестирования такой структуры не нужны те самые многомегабайтные исходные данные.
А>>>А чем плохо тестирование на многомегабайтных исходных данных? А>>>Заодно и эффективность потестируешь.
S>>Плохо тем, что такой тест писать сложно, а если их много — то надо сначала данные залить, потом запускать тест, потом сравнивать результаты с эталонными. Это долго, кроме того, требуется специальная тестовая база, что влечет геморрой с синхронизацией изменений итд. Вот я и хочу за счет усложнения структуры обойтись без них. Нужно тестировать не весь отчет сразу, а отдельные бизнес-правила, по которым (например) производятся начисления. S>Не вижу тогда особого смысла в таком тестировании, т.к. нормального покрытия тестами все-равно не будет, а создание такого специфичного тестирования будет сравнима с трудозатратами на стандартное unit-тестирование.
А вот и нет! Покрытие будет почти 100%, так как после выполнения бизнес-правил останутся только операции агрегирования, которые выполняет SQL Server. Трудоемкость же гораздо ниже.
Вы пробовали написать тест на обработку, например — рассчитать зарплату сотрудникам, при условии что есть таблица с рабочим временем — (сотр, выход на работу, уход) и стоимостью часов — с 9 до 18 — ХХХ, с 18 до 24 — УУУ.
Чтобы написать тест для процедуры, которая это считает, надо
1) забить список сотрудников
2) забить таблицу выхода на работу
3) забить таблицу результатов
4) сравнить две таблицы.
Либо, если ввести понятие начислений и тестировать функцию, рассчитывающую начисление одному сотруднику за одну смену — надо будет вызвать эту функцию раза три-пять с разными параметрами и сравнить числа.
Что проще?
плюс тестировать можно на рабочей базе.
S> Если сохранять версионность структуры данных, тестов и кода, то, при использовании некоторых автоматизирующих средств сборки и проверки проектов, можно получать после изменения любого проекта места, влияющие на работу той или иной части проекта (-ов). Ну а поставить на ночь сборку и тестирование всех связанных проектов, а на утро получить результаты — хорошая практика при разработке сложных или сильно взаимосвязанных проектов.
Это без сомнения, только как это сделать например для MS SQL, где есть база с большим количеством встроенных процедур (150 шт) и даже узнать, где процедура вызывается штатными средствами (EM) нельзя? Подскажите тогда чудо программу для этого..
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, Sshur, Вы писали:
S>Здравствуйте, stasukas, Вы писали:
S>>Здравствуйте, Sshur, Вы писали:
S>>>>>ой.. речь идет о том, что для тестирования такой структуры не нужны те самые многомегабайтные исходные данные.
А>>>>А чем плохо тестирование на многомегабайтных исходных данных? А>>>>Заодно и эффективность потестируешь.
S>>>Плохо тем, что такой тест писать сложно, а если их много — то надо сначала данные залить, потом запускать тест, потом сравнивать результаты с эталонными. Это долго, кроме того, требуется специальная тестовая база, что влечет геморрой с синхронизацией изменений итд. Вот я и хочу за счет усложнения структуры обойтись без них. Нужно тестировать не весь отчет сразу, а отдельные бизнес-правила, по которым (например) производятся начисления. S>>Не вижу тогда особого смысла в таком тестировании, т.к. нормального покрытия тестами все-равно не будет, а создание такого специфичного тестирования будет сравнима с трудозатратами на стандартное unit-тестирование.
S>А вот и нет! Покрытие будет почти 100%, так как после выполнения бизнес-правил останутся только операции агрегирования, которые выполняет SQL Server. Трудоемкость же гораздо ниже.
Покрытие 100% — это вручную подготовленные данные (корректные, некорректные, околограничные). На реальных живых данных не всегда достигается такое покрытие.
S>Вы пробовали написать тест на обработку, например — рассчитать зарплату сотрудникам, при условии что есть таблица с рабочим временем — (сотр, выход на работу, уход) и стоимостью часов — с 9 до 18 — ХХХ, с 18 до 24 — УУУ.
S>Чтобы написать тест для процедуры, которая это считает, надо S>1) забить список сотрудников S>2) забить таблицу выхода на работу S>3) забить таблицу результатов S>4) сравнить две таблицы.
Это делается один раз при создании теста.
S>Либо, если ввести понятие начислений и тестировать функцию, рассчитывающую начисление одному сотруднику за одну смену — надо будет вызвать эту функцию раза три-пять с разными параметрами и сравнить числа.
Получается, что это всего-лишь фича проектирования, когда производится промежуточное агрегирование. И эта ситуация начнет усложняться, если будет производиться модификация данных "задним числом" (практически всегда такое происходит — человеческий фактор операторов ввода данных).
S>Что проще?
S>плюс тестировать можно на рабочей базе.
Похоже всего-навсего на оперативный тест для проверки корректности данных при поступлении жалобы от пользователей. Еще раз скажу, что нет 100% покрытия по данным в рабочей базе.
S>> Если сохранять версионность структуры данных, тестов и кода, то, при использовании некоторых автоматизирующих средств сборки и проверки проектов, можно получать после изменения любого проекта места, влияющие на работу той или иной части проекта (-ов). Ну а поставить на ночь сборку и тестирование всех связанных проектов, а на утро получить результаты — хорошая практика при разработке сложных или сильно взаимосвязанных проектов.
S>Это без сомнения, только как это сделать например для MS SQL, где есть база с большим количеством встроенных процедур (150 шт) и даже узнать, где процедура вызывается штатными средствами (EM) нельзя? Подскажите тогда чудо программу для этого..
1. должен быть скрипт для билда пустой базы
2. должен быть скрипт для наполнения справочников
3. для каждого теста должен быть набор данных (исходных и результатов) — можно использовать одни и те же данные для разных тестов
Ну автоматизировать все это можно и с помощью обычных .bat файлов. Но я бы рекомендовал использовать CruiseControl.NET (обсуждался в этом форуме в январе-феврале этого года).
Делается это примерно так для каждого проекта: производится сборка проекта
генерируется база
заполняются справочники
для каждого unit-теста:
а. инициализируются данные
б. производится тестируемая операция
в. проверяются результаты
г. очищаются данные
удаляется база
Кто сказал, что ночи не хватит на подобные тестирования?
Здравствуйте, Sshur, Вы писали:
S>Здравствуйте, stasukas, Вы писали:
S>>>тестирование хотя бы встроенных процедур. А вообще — всего что есть в БД, вплоть до структуры таблиц. S>>
S>Ничего смешного. Есть 10 баз, отданных заказчикам,каждая из которых модифицировалась под конкретные условия. Таблицы могут отличаться по структуре. S>Потом берем и вводим новую функциональность в программу (и соответственно меняем базу). И вот нужно убедиться что та версия клиентского ПО, скомпилированная под конкретного заказчика, будет работать с новой базой. И случайное изменение структуры таблицы (например, программист подумал и решил, что данное поле теперь будет not null. А у заказчика возможен вариант с null в данных) может привести к неработоспособности базы.
S>Так что тут либо отказываться от поддержки, либо вводить тестирование всего что движеться
Естественно, что совсем каждый чих не стоит проверять. Тут необходимо выбирать золотую середину, ведь создается не система контроля АЭС.
Написание тестов одновременно с кодом не сильно напрягает, лучше, если этим будет заниматься специально заточенный человек. При этом происходит значительное повышение качества продуктов.
S>>>Насчет неудобств при тестировании отчета, который требует для себя кучи исходных данных, говорилось уже много. S>>>Смысл именно в том, чтобы не отходить от сущности unit-тестирования и обойтись без исходных данных. S>>В unit-тестировании исходные данные всегда нужны. А Ваш случай более похож на оперативную проверку в процессе эксплуатации. Да, это можно делать, но на этапе внедрения. В оперативной работе этого не требуется, т.к. вся работа системы в целом должна описываться unit-тестами с добавлением всех новых нестандартных ситуаций в поведении системы (багов) с момента их исправления. Таким обраом, система тестов будет постепенно разрастаться, но только за счет S>>добавления нового и, в основном, без модификации старого.
S>Исходные данные в виде заполненной таблицы с миллионом строк, вот что я имею ввиду. А исходые данные в виде параметров функции несомненно нужны.
S>>>>>Соответственно задача тестирования БД в первую очередь заключается в разработке такой структуры БД, которую удобно тестировать S>>>>Совсем не согласен, т.к. главная задача разработчика БД — это оптимальная производительность, а не удобство тестирования. Если "БД имееет дизайн, не подходящий для модульного тестирования", то необходимо пересмотреть свои взгляды на "модульное тестирование".
S>>>Ну это уже компромисс.. того что нужно в каждом конкретном случае. Я в своей области готов пожертвовать производительностью, чтобы постоянно быть полностью уверенным в работоспособности всех моих баз. Просто задача стоит поддерживать неограниченное количество схожих, но отличающихся в деталях баз. И чтобы стоимость внесения изменений не вызывала шок у заказчика S>>Думаю, что здесь кроется ошибка проектирования, т.к. в данном случае общие части должны быть вынесены отдельно от специфичных, а система тестирования по ним будет единой. Специфичные свойства системы могут совершенно спокойно расширять основные свойства системы. Для специфичных свойств каждой системы пишется свой набор таких же специфичных тестов. Вот такая комбинация и позволяет полностью охватить все системы тестами.
S>Это так и есть, проблема мною сформулирована выше. Могут изменяться и общие части, и какова взаимосвязь общих и специфичных частей уже никто не знает ввиду общей сложности системы.
Сори, может я некорректно выразился, но под "расширять" я подразумевал не модификацию общего куска, а вынесение его в отдельное место и использование его из более специфичных мест, которые однозначно меньше основной части. Например, есть класс СделатьУниверсальнуюОперацию с методом Делать, мы реализуем для каждого специфичного случая класс СделатьОперациюДляВасиПупкина с методом Делать, где вызываем СделатьУниверсальнуюОперацию.Делать и производим после (или до) специфические действия для Васи. Но это уже в другой форум.
S>>>ой.. речь идет о том, что для тестирования такой структуры не нужны те самые многомегабайтные исходные данные. S>>Так речь идет о промежуточной агрегации данных? S>Можно и так сказать. Наверно
Здравствуйте, kolam, Вы писали:
K>А вот здесь начинается магия.
Магией занимаются на других сайтах, а здесь вроде компьютерами
K>Ведь можно же сочетать и то и другое... но очень редко получается
Врядли получися сочетать и то и другое.
Один из эффектов применения unit-тестов — проработка архитектуры таким образом, чтобы тестирование стало возможным
Т.е. при использовании unit-тестов идет постоянный рефакторинг кода. А он плохо сочетается с производительностью.
ИМХО, так же и в этом случае.
Здравствуйте, kavlad, Вы писали:
K>Здравствуйте, kolam, Вы писали:
K>>А вот здесь начинается магия.
K>Магией занимаются на других сайтах, а здесь вроде компьютерами
K>>Ведь можно же сочетать и то и другое... но очень редко получается
K>Врядли получися сочетать и то и другое. K>Один из эффектов применения unit-тестов — проработка архитектуры таким образом, чтобы тестирование стало возможным K>Т.е. при использовании unit-тестов идет постоянный рефакторинг кода. А он плохо сочетается с производительностью. K>ИМХО, так же и в этом случае.
Ситуация решается удвоением количества процессоров на сервере Кстати, может оказаться дешевле, чем доработка базы при отсутствии тестов.
Вообще, жаль, что нет хорошей методологии и специализированных программных средств тестирования баз данных. Хотелось бы легко и не напрягаясь указывать, что для такой-то процедуры нужны такие-то и такие-то таблицы, (предположим из репозитория, куда они один раз уже были внесены), а выходом являются такие и такие.
Хотя даже при таком подходе проблем много..
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, Sshur, Вы писали:
S>Вообще, жаль, что нет хорошей методологии и специализированных программных средств тестирования баз данных. Хотелось бы легко и не напрягаясь указывать, что для такой-то процедуры нужны такие-то и такие-то таблицы, (предположим из репозитория, куда они один раз уже были внесены), а выходом являются такие и такие.
Я несколько сомневаюсь, что появление такой методологии возможно на данном этапе развития СУБД!
Эх, круто завернул
1. Разных СУБД слишком много — РСУБД, ООСУБД, XML-СУБД и прочая, прочая, прочая
2. Хотя и есть стандарты на SQL, напримре, на ООСУБД — производители почему-то эти стандарты исползуют как бумагу
(Видимо, из-за того что область достаточно бурно развивается) Поэтому общую методику может быть очень сложно выработать.
4. Unit-тесты ведь использутся для тестирования исполняемого кода. Не во всех СУБД есть такой код
И я совсем не понимаю, как можно протестировать "структуру таблиц" — в любом случае это не unit-тесты.
5. Мало того так и языковые средства круто разнятся — в одних СУБД есть курсоры в других нет, в тертьих даже нет транзакций,
оракул поддерживает код на Java, PostgreSQL — на всем что хочешь, а MSSQL про эти вещи слыхом не слыхивал, не говоря про MySQL.
6. Сам постулат — тестирование баз данных без данных, ИМХО, неверен. Так можно тестировать только процедуры
необращающиеся к таблицам за данными. В unit-тестах все равно используются тестовые данные. От этого никуда не денешься.
А по тестированию хранимых процедур могу посоветовать вот что:
1. если это возможно, то строить вторую процедуру, которая производит "обратные действия" и помещает куда-нибудь "восстановленные данные" проверка будет очень простая — сравнить две таблицы
2. придумывать простые пост- и предусловия, выполняющиеся до и после выполнения процедуры и проверять их в теятовых процедурах
Здравствуйте, kavlad, Вы писали:
K>Здравствуйте, Sshur, Вы писали:
S>>Вообще, жаль, что нет хорошей методологии и специализированных программных средств тестирования баз данных. Хотелось бы легко и не напрягаясь указывать, что для такой-то процедуры нужны такие-то и такие-то таблицы, (предположим из репозитория, куда они один раз уже были внесены), а выходом являются такие и такие.
K>Я несколько сомневаюсь, что появление такой методологии возможно на данном этапе развития СУБД!
А что такого в данном этапе? Что такое реляционная СУБД известно уже давно, смысл любых достаточно развитых систем един — есть данные и процедуры ( на чем они пишутся, не важно — TSQL, PL-SQL, java, .NET). Процедуры что-то делают с данными, имея на входе один набор и на выходе другой.
Тут конечно от деталей реализации много чего зависит, но хотя бы для MS SQL написать же можно.
K>4. Unit-тесты ведь использутся для тестирования исполняемого кода. Не во всех СУБД есть такой код
значит он есть в ПО
K> И я совсем не понимаю, как можно протестировать "структуру таблиц" — в любом случае это не unit-тесты.
ну давай назовем это тестом совместимости БД и ПО
K>5. Мало того так и языковые средства круто разнятся — в одних СУБД есть курсоры в других нет, в тертьих даже нет транзакций, K> оракул поддерживает код на Java, PostgreSQL — на всем что хочешь,
Код на всем чего хочвешь, это интересно — а как?
K>6. Сам постулат — тестирование баз данных без данных, ИМХО, неверен. Пусть это будет тестирование работоспособности БД, так лучше?
K>Так можно тестировать только процедуры, необращающиеся к таблицам за данными. В unit-тестах все равно используются тестовые данные. От этого никуда не денешься.
Но вопрос-то в том и заключается, что тестовыми данными может быть и вся БД, и несколько параметров. Все зависит от степени декомпозиции
А когда исходными данными являются несколько таблиц, это ИМХО уже не unit, а функциональные тесты получаются
K>А по тестированию хранимых процедур могу посоветовать вот что: K>1. если это возможно, то строить вторую процедуру, которая производит "обратные действия" и помещает куда-нибудь "восстановленные данные" проверка будет очень простая — сравнить две таблицы K>2. придумывать простые пост- и предусловия, выполняющиеся до и после выполнения процедуры и проверять их в теятовых процедурах
Это слишком муторно делать и поэтому у разработчика велик соблазн не писать тест для процедуры. Да и по времени очень напряжно, вероятность ошибки велика.
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, Sshur, Вы писали:
S>ну давай назовем это тестом совместимости БД и ПО
И чем это отличается от обычных unit-тестов этого же ПО ?
S>Код на всем чего хочвешь, это интересно — а как?
Хотя бы так
S>Это слишком муторно делать и поэтому у разработчика велик соблазн не писать тест для процедуры. Да и по времени очень напряжно, вероятность ошибки велика.
Не надо так говорить — эти же отмазки я слышал и про unit-тесты
Все зависит от архитектуры — разве об этом не говорилось в вашем же посте?
ИМХО, unit-тесты дают ошутимую выгоду лишь при определенных условиях. Важнейшим из условий является разделение интерфейса и реализации в коде — в СУБД с этим проблемы, кроме случая постоянного переписывания одних и тех же процедур не изменяя их сигнатуры.
И главное — обычно ведь происходит тонкая настройка БД для оптимизации производительности, даже ее архитектура у более-менее грамотного проектирвщика обязательно затачивается под производительность. А перделка под удобное тестирование скорее всего разрушит эту оптимизацию.
И вторым процессором здесь врядли спасешься. Но об этом уже говорили другие.
... По ушам лупит Гражданская Оборона — Песня красноармейца
Здравствуйте, Sshur, Вы писали:
S>Это слишком муторно делать и поэтому у разработчика велик соблазн не писать тест для процедуры. Да и по времени очень напряжно, вероятность ошибки велика.
Ну не могу спокойно воспринять эти слова
Unit-тесты и функциональные тесты тоже муторно делать и соблазн также велик, если не еще выше. И по времени — покрыть все классы приложения тестами — чуть не вдвое больше времени уходит на кодирование.
Как только сложность проекта возрастет — тесты неизбежны
Кстати, сложность хранимых процедур тоже может свидетельствовать об ошибках проектирования структуры БД или приложения.
... По ушам лупит Гражданская Оборона — Песня о циркаче
K>И главное — обычно ведь происходит тонкая настройка БД для оптимизации производительности, даже ее архитектура у более-менее грамотного проектирвщика обязательно затачивается под производительность. А перделка под удобное тестирование скорее всего разрушит эту оптимизацию. K>И вторым процессором здесь врядли спасешься. Но об этом уже говорили другие.
Ну у меня есть конкретная база данных, которую мне хотелось бы тестировать. Про нее я знаю, что запас по производительности есть. Поэтому я огу себе позволить менять структуру под тесты и удобство раззаботки..
А вообще эти слова — про то, что надо затачивать под производительность и прочее — напоминают слова низкоуровневого программиста о преимуществах ассемблера перед java или C# — никто не спорит, что java медленне, но ведь сложные проекты на ассемблере не пишут, и покупают для работы сейчас копьютеры, способные на C# выполнять те же задачи, что и 486 на ассемблере. Только стоимость разработки сейчас ниже и сложность программ такая, что не снилась во времена процедурного программирования.
Поэтому заточка под производительность рано или поздно уйдет в сторону перед удобством проектирования и тестирования.
К тому же мне кажеться, что возможно совмещать и то, и то — по крайней мере на уровне компромисса Пусть в 2 раза медленнее считает, зато ошибок не так много
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Здравствуйте, Sshur, Вы писали:
S>А вообще эти слова — про то, что надо затачивать под производительность и прочее — напоминают слова низкоуровневого программиста о преимуществах ассемблера перед java или C#
ИМХО, не надо путать божий дар с яичницей Произошел качественный скачек в развитии железа — поэтому стало возможным ослабить требования к производительности, оптимизации кода в ряде задач. СУБД все еще остаются "тяжеловесными" задачами, требующими тонкой настройки.
S>Поэтому заточка под производительность рано или поздно уйдет в сторону перед удобством проектирования и тестирования.
Возможно. Очень даже. Но... Работа с БД очень часто является критическим местом приложения, здесь часто скрыты затыки производительности.
По первому посту у меня сложилось впечатление, что есть достаточно сложные процедуры, которые трудно проверить ручками.
TTD как раз и приучает к тому, что код должен быть простым, иначе его сложно тестировать
Я уже говорил, что может быть стоит посмотреть на архитектуру БД — разбить сложную процедуру на несколько простых, хранить промежуточные результаты и т.п.
S>К тому же мне кажеться, что возможно совмещать и то, и то — по крайней мере на уровне компромисса Пусть в 2 раза медленнее считает, зато ошибок не так много
Не все задачи могут перенести такое падение производительности. А БД имеют свойство разрастаться
Вам захочется пользоваться гуглом, если он будет искать в два раза медленнее
И еще хорошо, если в два
Я согласен, что инструменты разработчика БД очень отстают от инструментов программирования, но, видимо, БД не совсем созрели для такого поворота событий. Хотя языковые средства в них все больше усложняются, и, вполне возможно, что скоро появится какое-то средство тестирования.
Хотелось бы узнать подробнее, как вы видите себе такой инструмент.
... По ушам лупит Tiamat — However You Look At It Loose