Дорогое обслуживание с помощью автоматических данных испытаний

В моей компании у нас есть растущий набор тестов интеграции с использованием JUnit в веб-приложении Java. В каждом тесте используются некоторые конкретные внешние XML файлы для заполнения базы данных необходимыми данными для теста. Проблема заключается в следующем:

  • Когда происходит изменение модели, мы долгое время исправляем все файлы XML (у нас есть сотни XML файлов, многие из них с избыточным кодом).
  • Сложность создания файла XML вручную препятствует программисту исследовать различные сценарии.
  • У нас нет связи между тестовыми данными и тестом (например, во время теста я не знаю "имя" пользователя, вставленного XML). Мы могли бы жестко скопировать нужную нам информацию, но это также увеличило бы время обслуживания, чтобы синхронизировать как XML, так и жестко кодированные данные.

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

  • Изменения в модели требуют изменения CRUD в любом случае, поэтому больше не потребуется исправлять тестовые данные.
  • Было бы проще собрать, протестировать данные, потому что мы не будем беспокоиться о вещи, например, о совпадении идентификатора и внешнего ключа объекта вручную.
  • У меня были бы все важные данные в переменных с синхронизацией, гарантированной IDE.

но для меня у него нет опыта и знаний, чтобы начать этот подход. Вопрос в том: Является ли это решение эффективным? Вызывает ли этот подход другие проблемы? Где я могу найти этот подход в литературе? Есть ли лучшее решение перечисленных проблем?

Ответ 1

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

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

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

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

Ответ 2

Похоже, что ваша существующая система использует что-то вроде DBUnit, где тесты начинаются с чистой базы данных. Тест включает в себя этап настройки, который загружает данные из одного или нескольких файлов XML в базу данных, а затем тест выполняется против этих данных.

Вот некоторые из преимуществ такого подхода:

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

  • В каждом тесте может быть очень четко указано, какие данные необходимы для запуска теста. Иногда с моделью домена между такими вещами, как необязательные ассоциации и ленивая загрузка, какие объекты загружаются, может быть неясно. (Здесь я особенно задумываюсь о Hibernate, где много раз последствия отображения могут быть сложными.) Напротив, если данные настроены более декларативным образом, указывая, какие строки входят в какую таблицу, начальное состояние является явным.

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

В DBUnit вы можете написать script, чтобы автоматизировать создание вашего XML из содержимого базы данных, чтобы вы могли воссоздать состояние, в котором вы нуждаетесь, и сохранить его как XML. Не нужно создавать данные теста вручную.

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

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