Вариант использования: у нас есть довольно большая база данных (около 200 таблиц), которая используется в большой (устаревшей) системе. Он реализован в виде подхода, основанного на базе данных, с одним файлом edmx, определяющим всю базу данных. Мы используем XUnit и Effort для автоматического тестирования. Проблема в том, что эти тесты очень медленные. Для запуска нашего текущего набора тестов требуется около 7-8 минут, даже несмотря на то, что охват тестированием далеко не такой, каким мы хотим его видеть.
Я заметил, что если я создаю меньшее подмножество файла edmx , удаляя ненужные таблицы, тесты запускаются быстрее.
Я ищу решение, в котором для конкретного теста или набора тестов мы можем каким-то образом заставить Effort создать только подмножество таблиц, которые необходимы (я думаю, что во многих случаях нам понадобится только одна таблица).
В настоящее время мы настраиваем наше соединение следующим образом:
connection = EntityConnectionFactory.CreateTransient("metadata=res://entities.csdl|res://entities.ssdl|res://entities.msl");
Есть ли способ, которым мы можем (например, запустив преобразование XML во время выполнения), заставить Effort создавать только структуры данных, которые ему нужны для поднабора таблиц, которые мы определяем?
Отказ от ответственности : я владелец проекта Entity Framework Effort
В нашей библиотеке есть функция, позволяющая создать точку восстановления и выполнить откат к ней.
Таким образом, используя этот прием, вы можете использовать CreateRestorePoint()
только один раз, когда все таблицы созданы, а затем для каждого теста запустите их с RollbackToRestorePoint
. (Есть несколько других способов заставить это работать, но я думаю, вы поняли смысл)
Это, без сомнения, сделает ваш тестовый запуск ОЧЕНЬ большим, поскольку таблицу не нужно создавать каждый раз.
Вот пример:
var conn = Effort.DbConnectionFactory.CreateTransient();
using (var context = new EntityContext(conn))
{
context.EntitySimples.Add(new EntitySimple { ColumnInt = 1 });
context.EntitySimples.Add(new EntitySimple { ColumnInt = 2 });
context.EntitySimples.Add(new EntitySimple { ColumnInt = 3 });
context.SaveChanges();
}
// Create a RestorePoint that will save all current entities in the "Database"
conn.CreateRestorePoint();
// Make any change
using (var context = new EntityContext(conn))
{
context.EntitySimples.RemoveRange(context.EntitySimples);
context.SaveChanges();
}
// Rollback to the restore point to make more tests
conn.RollbackToRestorePoint();
Отдельный юнит-тест и интеграционный тест. Для тестирования интеграции вы можете использовать базу данных и работать в более высоких средах (чтобы сэкономить время), но в локальных средах вы можете использовать Faker \ Bogus и NBuilder для генерации массивных данных для модульного тестирования.
https://dzone.com/articles/using-faker-and-nbuilder-to-generate-massive-data
Другой вариант - вы можете создать файл ресурсов, соответствующий вашим тестовым кейсам https://www.danylkoweb.com/Blog/the-fastest-way-to-mock-a-database-for-unit-testing-B6.
Я также хотел бы познакомить вас с производительностью InMemoryDB и SqlLite, http://www.mukeshkumar.net/articles/efcore/unit-testing-with-inmemory-provider-and-sqlite-in-memory-database-in- эф-ядро
Хотя приведенный выше пример относится к EFCore, в EF6 мы также можем использовать SqlLite https://www.codeproject.com/Tips/1056400/Setting-up-SQLite-and-Entity-Framework-Code-First
Поэтому я рекомендую вам использовать sqllite для сценариев тестирования интеграции. Для модульного теста вы можете использовать либо sqllite, либо Faker \ Bogus и NBuilder.
Надеюсь, поможет!