Comments 25
Почему у Вас возникает проблема подключённых пользователей? Можно же просто создавать для тестов совершенно новую базу данных, имя которой никто кроме Вас не знает и соединиться кроме тестового скрипта не может.
+7
Не вижу особой разницы — разворачивать бэкап каждый раз в новую базу или в одну и ту же. Есть ли разница в скорости?
Ещё вопрос — вы предлагаете создавать базу на прогон или на каждый тест?
Ограничить права по подключениям — кажется, здраво. Но как и любая строгость — ведёт к неудобствам. Хочется без заморок подключаться к тестовой базе, используя какой то стандартный логин/пароль и известное имя. Я не обижусь, если меня выкинет, когда я помешаю системе работать.
Ещё вопрос — вы предлагаете создавать базу на прогон или на каждый тест?
Ограничить права по подключениям — кажется, здраво. Но как и любая строгость — ведёт к неудобствам. Хочется без заморок подключаться к тестовой базе, используя какой то стандартный логин/пароль и известное имя. Я не обижусь, если меня выкинет, когда я помешаю системе работать.
-1
У Вас основное, что делает Ваша система подготовки базы — это отключение пользователей. 1) а этим пользователям работать с базой не нужно? и 2) вы запускаете тесты в базе, в которой кто-то уже пошалил и в принципе непонятно годится ли она в качестве эталонной базы. Все проблемы решаются одним — для всего прогона, или для каждого отдельного теста — как будет лучше — создавать новую базу. Можно нового пользователя для подключения к ней — заодно оттестируете и этот аспект, ошибки при смене имени пользователя тоже бывают.
В результате две страницы скриптов превращаются в одну строчку восстановления базы из архива :)
В результате две страницы скриптов превращаются в одну строчку восстановления базы из архива :)
+1
Признаться, было просто просто интересно написать отключающий скрипт и поглядеть как оно работает. Ну а бенефит как раз и получился в том, что базу менять не надо.
В целом, согласен, что решение с созданием базы вяглядит проще.
Не понял тезис про «пошалил» — я ведь перед тестом из бекапа восстанавливаю. Там только если успеть во время теста что то сделать.
В целом, согласен, что решение с созданием базы вяглядит проще.
Не понял тезис про «пошалил» — я ведь перед тестом из бекапа восстанавливаю. Там только если успеть во время теста что то сделать.
0
Могу вам посоветовать вместо KILL использовать 'ALTER DATABASE SET OFFLINE WITH ROLLBACK IMMEDIATE'
+2
Категорические поддерживю. Приведенный ТС килл-код во-первых громоздок, во-вторых не исключает подключений в процессе тестирования. Но только сделал бы не SET OFFLINE, а SET SINGLE_USER.
+1
Поставил "-" за «Юнит-тесты и БД», если есть база данных то тесты как минимум интеграционные
0
Не совсем понял, зачем городить такой огород с откатами, когда есть транзакции, поэтому опишу работающую схему в том виде, как это происходит у нас.
Для тестов используется отдельная база, с имеющимся необходимым набором данных, которая лежит на сервере и доступна всем и каждому и на всякий случай каждую ночь восстанавливается из бэкапа.
Если тест изменяет какие-то данные, он оборачивается в транзакцию (TransactionScope в .NET, например), которая после выполнения теста отказывается — таким образом главная задача оставить состояние в том виде, которое было до выполнения теста, решается.
При необходимости добавить в тестовую базу новые данные, они добавляются и делается бэкап, который подменяет тот, который используется для ночного восстановления.
Для тестов используется отдельная база, с имеющимся необходимым набором данных, которая лежит на сервере и доступна всем и каждому и на всякий случай каждую ночь восстанавливается из бэкапа.
Если тест изменяет какие-то данные, он оборачивается в транзакцию (TransactionScope в .NET, например), которая после выполнения теста отказывается — таким образом главная задача оставить состояние в том виде, которое было до выполнения теста, решается.
При необходимости добавить в тестовую базу новые данные, они добавляются и делается бэкап, который подменяет тот, который используется для ночного восстановления.
0
Ну и конечно юнит-тесты в идеале к БД отношения не имеют, это уже скорее интеграционное тестирование.
+2
Хм, а какое решение, если тестируемый модуль работает с базой данных? Делать какую-то абстракцию и использовать заглушки?
+1
Ну да, абстракция, мок-объекты.
+1
А если за работу с базой отвечает ORM? Много труда будет используемые фишки ORM закрывать через mock-объекты. Хотя это, конечно, правильнее :)
+1
Стандартная и часто описываемая ситуация: есть ORM, есть репозиторий, через ORM тягающий данные. Создаются mock-репозитории, остальное не меняется.
На деле же конечно не всегда все получается так радужно, многие работают сразу напрямую в бизнес-логике через ORM, без всяких прослоек. Так что суровая реальность иногда играет роль, тут вы правы.
На деле же конечно не всегда все получается так радужно, многие работают сразу напрямую в бизнес-логике через ORM, без всяких прослоек. Так что суровая реальность иногда играет роль, тут вы правы.
0
Для сколь-нибудь серьезного теста использовать транзакцию может быть очень накладно по времени. Я бы даже сказал ооооочень.
-1
Если уж на то пошло, то юнит тесты на то и юнит тесты, что бы тестировать очень небольшой кусок, о каких серьёзных тестах речь?
Кроме того, это не накладнее по времени, чем делать какие-то откаты после каждого теста скриптами. Если же откаты не делать после каждого теста, а делать после выполнения целой тест-сессии, то нарушается весь принцип тестирования — каждый предыдущий тест начинает влиять на следующий.
Кроме того, это не накладнее по времени, чем делать какие-то откаты после каждого теста скриптами. Если же откаты не делать после каждого теста, а делать после выполнения целой тест-сессии, то нарушается весь принцип тестирования — каждый предыдущий тест начинает влиять на следующий.
0
Давайте себе представим простейший тест, который сравнивает вычисляемое некоторой функцией значение с заданным. За функцией же кроется замысловатый агрегат по некоторым тестовым наборам данных, которые определены на десятках таблиц с миллионами записей. Это «очень небольшой кусок» или как? А если в процессе заполнения этим тестовым набором данных я буду тестировать процедуры заполнения — это будет «нарушение принципа тестирования»?
В общем и целом я просто хотел предупредить, поскольку именно этот способ мы использовали долгое время, что иногда можно столкнуться с ситуацией, когда роллбек после теста идет от нескольких часов, до нескольких дней. И речь идет не о каких-то абстрактных тестах, а конкретных требованиях и наборах данных, полученных от конкретных заказчиков, с конкретным требованием в ТЗ, чтобы во время приемо-сдаточных испытаний получаемые значения соответствовали эталонным.
В общем и целом я просто хотел предупредить, поскольку именно этот способ мы использовали долгое время, что иногда можно столкнуться с ситуацией, когда роллбек после теста идет от нескольких часов, до нескольких дней. И речь идет не о каких-то абстрактных тестах, а конкретных требованиях и наборах данных, полученных от конкретных заказчиков, с конкретным требованием в ТЗ, чтобы во время приемо-сдаточных испытаний получаемые значения соответствовали эталонным.
0
Абсолютно также делаем. TransactionScope — лучшее и самое красивое решение.
0
А если у нас в тестах есть свои транзакции, и тесты исследуют подробности их проведения или отката?
Возможны ли какие то сторонние эффекты от такого подхода?
Возможны ли какие то сторонние эффекты от такого подхода?
+1
интересно, можно ли (теоретически, хотя бы) на небольшом базовом наборе нагородить таких транзакций, чтобы они откатывались дольше применения бекапа?
0
Чисто теоретически — да, практически — нужно очень много данных. Тут дело не в количестве транзакций, а в количестве модифицированных страниц в базе (т.е. операций вставки/удаления/обновления). Чем больше страниц изменено/добавлено -> тем больше записей в журнале транзакций -> тем больше изменений нужно откатывать. А вообще — it depends. Я попробовал сделать это у себя и вот что получилось: я добавил одну строку и затем обновил её же 500000 раз (все это, конечно же, в одной транзакции). Откат этих операций занял примерно 3222 ms. Восстановление базы из бэкапа — 1728 ms.
0
момент первый — «юнит-тесты работают с базой и меняют её» — это, извините, ни в какие ворота. при тестировании работы с базой уместно говорить об интеграционных тестах.
момент второй — используйте FluentMigrator
момент второй — используйте FluentMigrator
0
Sign up to leave a comment.
Тесты и БД. Как откатить изменения, сделанные тестом?