在我们的一个项目中,我们有一个有很多表和数千行的数据库。对于我们的集成测试,我们希望我们的测试是针对一个固定的数据库状态运行的,例如,5000行,这样测试是确定性的,总是返回相同的结果。
我们之前曾使用过一个小型的Entity Framework Core InMemoryDatabases,其中我们添加了像这样的20行。
private DbContextOptions<OurDataContext> GetInMemoryDbContextOptions()
{
var options = new DbContextOptionsBuilder<OurDataContext>()
.UseInMemoryDatabase(databaseName: "foo")
.Options;
using (var context = new OurDataContext(options))
{
context.OurTable.Add(new OurTable(){...});
// ...
context.SaveChanges();
}
return options;
}
然而,在我们的新案例中,这是不可行的 这么多的行,应该从生产数据库中提取。我们需要一个很好的方法将真实的数据同步到我们的内存数据库中。如何才能做到这一点呢?
理想情况下,我们会用SQL Management Studio将生产数据库的相关部分导出到一个SQL脚本中,并在Git中跟踪这个SQL导出,作为我们测试代码的一部分。就我们所见,目前还没有任何的 从SQL脚本导入数据 由于我们无法对其运行SQL脚本。
https:/docs.microsoft.comen-usefcoremiscellaneoustesting。 总结了这些可用的选项,但我还是不知道我们的解决方案是怎样的,因为我们需要的是
我们应该选择哪种内存数据库的方式?
按照OP的要求,把我的评论移到回答上。
根据你发布的EF Core链接,关于测试(https:/docs.microsoft.comen-usefcoremiscellaneoustesting。)很明显,使用内存(甚至SQL Lite)并不是 "推荐 "的,只是因为你测试的东西不能反映你的生产场景。也许有人会说,你不应该测试db的实现,但实际上,大多数时候这是必要的。例如,我想测试我创建的一个View是否返回了预期的结果,或者正确地生成了一个报表,所以我认为像OP问的那样使用一个完整的fletched SQL Server是一个合理的观点。另外一点是,使用像SQL Lite这样的东西并不能很好地支持你使用EF的所有迁移。例如我在创建索引时已经遇到了问题。
继续说下去。你可以尝试解决这个问题的一个方法是使用Docker容器。你可以在Linux容器中运行SQL Server 使用Docker运行SQL Server容器镜像. 这个想法是,你可以创建一个自定义的图像,基于SQL Server和图像内,你把你的5000行(或任何你想要的数据),建立和推送即用的图像到docker注册表。
然后在你的系统CI期间,你想用预期的数据运行你的测试,你启动你创建的镜像的docker容器,让你的测试连接到那个SQL Server实例(只需要将端口映射到主机,通常是1433)。这样你就可以保证你的测试总是以相同的数据集启动。
至于构建映像本身,你可以通过多种方式进行。你可以有一个CI本身来创建映像。它可以从某个地方获取数据,或者让一个小程序为你生成数据并将其放在容器内。它可以是一个.bak文件,也可以是一个SQL脚本,里面有一堆由你的程序生成的Inserts。然后当你想让你的映像有 "新 "数据时,你需要做的就是运行CI构建。你可以在Docker镜像中添加标签,以确保你可以针对新旧版本的数据运行测试,这很酷。
这也是需要考虑的事情。当你的数据库发生变化时,你可能还需要更新镜像(迁移),但你也可以通过总是从最新版本的模式中创建镜像,或者通过使用 MigrateAsync
在CI过程中生成图像。当然,这很大程度上取决于你的DB改变的频率。
我为Postgres数据库做了类似的事情,这些链接帮助我开始了工作。对于SQL Server来说也应该是非常相似的。