我对此主题进行了广泛搜索,结果发现零结果完全符合我的意愿。
从高层次来看,这就是我要做的:
这有什么意义?
好在上面的断言中有很多描述;数据的完整性。此项目中的迁移是在使用Database.Migrate()
的应用启动时运行的。我想确保现有数据不会丢失/损坏。
我在集成测试中遇到的所有示例都运行Database.Migrate()
作为测试设置的一部分,然后进行播种,然后进行断言。但是,这仅在测试具有 latest 模式(已应用所有迁移)的数据访问层时有用。在测试特定迁移对已经存在的数据的影响时没有用。
问题:
其他人如何解决跨迁移测试数据完整性的问题?我正在寻找一种适合CI管道的设置。
答案 0 :(得分:3)
请查看我的其他答案,因为它比以下方法更新且简单得多。
我能想到的一种方法如下:
(请注意,我还没有对此进行测试,这只是理论上的问题,所以请随时评论我可能出了什么问题。我在最后做笔记的目的是解决我看到的问题;笔记对应于项目标有*或^)
假设您已经有迁移 IM,M1,M2,...,Mn ,其中 IM 是初始迁移,而迁移 Mn 是上次成功测试的迁移。现在,假设您要测试新的迁移 Mn + 1 ,这是(除其他事项外)将User
实体更新为不再具有单独的FirstName
和LastName
个属性,但是只有一个Name
个属性。让我们给它命名为MergeFistAndLastNames
。
在继续进行测试方法之前,您必须在应用迁移 Mn + 1 之前完全捕获被测系统(SUT)的状态。因此,请执行以下操作:
Before_MergeFistAndLastNames
为后缀(例如)。因此,由于实体User
需要更新,因此将其副本放置在测试项目中并命名为User_Before_MergeFirstAndLastNames
。MembershipContext
需要更新,请在测试项目中进行复制,然后将其命名为MembershipContext_Before_MergeFirstAndLastNames
。
现在为您的测试方法^^,您将:
IMigrator.Migrate
应用所有迁移,直到及包括 Mn 。然后调用所需的服务来播种测试数据库**。IMigrator.Migrate
,应用迁移 Mn + 1 。
注意:
*:如果将上下文复制到测试项目,则其中的与更新后的实体相对应的任何DbSet
属性都需要手动编辑以使用复制的实体。例如,在上面的示例中,如果MembershipContext_Before_MergeFirstAndLastNames
具有属性DbSet<User> User {get; set;}
,则必须将其更改为DbSet<User_Before_MergeFirstAndLastNames> User {get; set;}
。
**:您可能需要拨打多个服务。如果您到处都在使用IoC,则注入复制的服务应该相对容易。
***:数据完整性声明实际上取决于您正在测试的特定迁移及其潜在影响。对于上面给出的示例,可能值得检查的是,使用(旧的)单独的名字和姓氏作为种子的用户仍然可以通过更新后的UserService
检索到,后者应返回User
Name
等于姓和名的串联。
^:在测试新迁移时,需要清除迁移测试项目中的所有内容。
非正式证明:让我们假设这不是必需的。使用上面的示例,该项目将包含一个测试方法,该测试方法将引用与迁移 Mn + 1 相对应的User
实体。现在,假设对User
进行了更新,这导致了更新的迁移 Mn + 2 。如果现有测试方法以不再适用的方式引用User
,则可能无法再编译。 ∎
上面的技术将在CI设置中很好地工作,在CI设置中,所有之前的迁移在合并到生产中之前都已经过测试。在这样的设置中,只有对测试最新迁移感兴趣的人才有意义。
^^:对于测试Up
迁移效果的每种测试方法,都需要一种反向测试方法来测试相应的Down
迁移效果。
答案 1 :(得分:0)
这是一种比我描述的方法简单得多的方法。
安排:使用IMigrator.Migrate
将所有迁移应用到(并包括)之前需要测试的迁移。
然后是密钥:使用SqlCommand
直接为数据库添加种子。
操作:应用需要测试的迁移。
声明。