Подтвердить что ты не робот

Интеграция Тестирование лучших практик

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

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

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

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

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

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

Спасибо!

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

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

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