4

用例:我们有一个非常大的数据库(大约 200 个表),用于大型(遗留)系统。它是作为一种数据库优先的方法实现的,一个edmx文件定义了整个数据库。我们使用 XUnit 和 Effort 进行自动测试。问题是这些测试非常慢。运行我们当前的测试套件需要大约 7-8 分钟,即使测试覆盖率远不及我们想要的。

我注意到,如果我创建一个较小的edmx文件子集,通过删除一些不需要的表,测试运行得更快。

我正在寻找一种解决方案,对于特定的测试或测试套件,我们可以以某种方式使 Effort 只创建所需的表子集(我认为在许多情况下,我们只需要一个表)。

目前我们正在像这样设置我们的连接:

connection = EntityConnectionFactory.CreateTransient("metadata=res://entities.csdl|res://entities.ssdl|res://entities.msl");

有什么方法可以(例如,通过在运行时运行 XML 转换)让 Effort 只为我们定义的表子集创建它需要的数据结构?

4

2 回答 2

4

免责声明:我是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();
于 2019-11-21T19:19:03.530 回答
0

分离出单元测试和集成测试。对于集成测试,您可以使用数据库并在更高的环境中运行(以节省时间),但在本地环境中,您可以使用 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- EF核心

虽然上面的例子是针对 EFCore 的,但在 EF6 中我们也可以使用 SqlLite https://www.codeproject.com/Tips/1056400/Setting-up-SQLite-and-Entity-Framework-Code-First

因此,我对您的建议是使用 sqllite 进行集成测试场景。对于单元测试,您可以使用 sqllite 或 Faker\Bogus 和 NBuilder。

希望能帮助到你!

于 2019-11-22T20:54:54.550 回答