Каким образом методы обновления таблиц базы данных должны подвергаться модульному тестированию?

У меня есть приложение, которое интенсивно использует базу данных. Большинство методов приложений обновляют данные в базе данных. Некоторые вызовы являются обертками для хранимых процедур, в то время как другие выполняют обновление кода в коде с использованием сторонних API.

Что я должен тестировать в своих юнит-тестах? Нужно ли мне...

  1. Проверьте, что каждый метод завершается, не вызывая исключения
  2. Проверяйте данные в базе данных после каждого теста, чтобы убедиться, что состояние данных соответствует ожидаемому

Моя первоначальная мысль - №2, но меня беспокоит то, что я буду писать кучу фреймворк-кода для моих модульных тестов. Я читал, что вы не должны писать кучу фреймворка для модульного тестирования.

Мысли?

РЕДАКТИРОВАТЬ: То, что я имею в виду под фреймворком, это написание тонны другого кода, который служит библиотекой для кода модульного тестирования... а не стороннего фреймворка.

7 ответов

Решение

Я делаю номер 2, т. Е. Проверяю обновление, обновляя запись, а затем считывая ее обратно и проверяя, совпадают ли значения с теми, которые вы ввели. Выполните обновление и чтение в транзакции, а затем сверните это обратно, чтобы избежать постоянного воздействия на базу данных. Я не думаю об этом как о тестировании кода Framework, так же как и о тестировании кода ОС или сетевого кода... Каркас (если вы имеете в виду компонент уровня доступа к базе данных, не относящийся к конкретному приложению) должен быть протестирован и проверен независимо.

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

Этот метод может быть использован в дополнение к тестированию на действующей базе данных. Это не то же самое, что тестирование на действующей базе данных, и не должно заменять такого рода тестирование. Но его можно использовать, по крайней мере, для проверки того, что вызов обновления базы данных вашим классом был сделан с правильными входными данными. Он также обычно работает намного быстрее, чем запуск тестов на реальной базе данных.

Если вы не пишете в базу данных вручную и используете вместо этого фреймворк (jvm, .net framework, ...), вы можете смело предположить, что фреймворк правильно пишет в базу данных. То, что вы должны проверить, правильно ли вы используете фреймворк.

Просто издевайтесь над методами и объектами базы данных. Проверьте, правильно ли вы вызываете их и получаете данные обратно. Это даст вам возможность легче писать тесты, выполнять их намного быстрее и делать их параллельными без каких-либо проблем.

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

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

Помните: цель - 100% покрытие тестами, а не 100% покрытие тестами; это включает в себя все ваши тесты: юнит, интеграция, функционал, система, приемка и руководство.

Вы должны проверить фактическое влияние кода на данные и его соответствие правилам валидации и т. Д., А не только то, что не возникает никаких исключений - это было бы похоже на простую проверку компиляции процедуры!

Трудно тестировать код базы данных, который выполняет вставки, обновления или удаления (DML), потому что тест изменяет среду, в которой он выполняется, то есть базу данных. Запуск одной и той же процедуры несколько раз подряд может (и, вероятно, должен) приводить к разным результатам каждый раз. Это очень отличается от модульного тестирования "чистого кода", который вы можете запускать тысячи раз и всегда получать один и тот же результат - то есть "чистый код" является детерминированным, а код базы данных, который выполняет DML, - нет.

По этой причине вам часто требуется создать "каркас" для поддержки модульных тестов базы данных, то есть сценариев, чтобы установить некоторые тестовые данные в правильном состоянии и выполнить очистку после запуска теста.

Я использую DBUnit, чтобы загрузить базу данных данными, выполнить логику обновления и, наконец, прочитать обновленные данные из базы данных и проверить их. В основном № 2.

Если логика обновления сложна, тогда вы должны сделать #2.

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

Другие вопросы по тегам