Лучшие практики тестирования интеграции - PullRequest
19 голосов
/ 25 августа 2009

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

Как вы можете себе представить, все это занимает довольно много времени (около 7-8 минут, чтобы бежать и быстро расти). Выполнение этого как части нашего CI (CruiseControl.Net) не является проблемой, но локальный запуск занимает много времени и действительно запрещает запускать их перед принятием кода.

Мой вопрос: есть ли рекомендации, которые помогут ускорить выполнение этих типов интеграционных тестов?

Я не могу выполнить их в памяти (а-ля sqlite), поскольку мы используем некоторые специфические функции базы данных (вычисляемые столбцы и т. Д.), Которые не поддерживаются в sqlite.

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

Как вы делаете это в своем магазине и что работает хорошо?

Спасибо!

Ответы [ 5 ]

15 голосов
/ 25 августа 2009

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

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

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

11 голосов
/ 25 августа 2009

в NUnit вы можете украсить свои тестовые классы (или методы) атрибутом, например:

[Category("Integration")]
public class SomeTestFixture{
    ...
}
[Category("Unit")]
public class SomeOtherTestFixture{
    ...
}

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

5 голосов
/ 25 августа 2009

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

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

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

3 голосов
/ 25 августа 2009

У нас есть экземпляр SQL Server Express с одинаковым определением базы данных, работающим для каждого компьютера разработчика, как часть среды разработки. При проверке подлинности Windows строки подключения стабильны - в строке нет имени пользователя / пароля.

Что нам действительно хотелось бы сделать, но пока нет, так это посмотреть, сможем ли мы заставить нашу систему работать на SQL Server Compact Edition , которая похожа на SQLite с ядром SQL Server. Затем мы можем запустить их в памяти, а также, возможно, параллельно (с несколькими процессами).

3 голосов
/ 25 августа 2009

Проводили ли вы какие-либо измерения (используя таймеры или аналогичные устройства), чтобы определить, где тесты проводят большую часть своего времени?

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

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