使用数据库模式进行SpecFlow集成测试

我正在尝试设置SpecFlow进行集成/验收测试.我们的产品在sqlite中有一个支持数据库(虽然不是很大).

事实证明这实际上是一个有点棘手的问题;如何为测试建模数据库

我想知道其他人使用什么模式进行与后备数据库的集成/验收测试.

我可以想到以下方法

>使用测试将数据库编译到程序集中,然后为每个测试进行阴影复制.虽然似乎很慢.
>我可以在内存中创建数据库并使用预先确定的数据填充它.
>我可以在内存中创建数据库,并以某种方式让Givens填充数据库.这似乎会使测试变得非常糟糕,但可能会给他们更多的控制并使测试不那么脆弱.
>我可以抽象每个数据库交互并使用模拟.不喜欢这个想法,因为我也想用它来测试数据库交互.
>将数据库编译到测试中并依赖清理代码将其返回到基本状态(这对我来说似乎很狡猾).不希望对事务执行此操作,因为将与某些测试进行多次交互(因此编写项目然后尝试使用不同的权限读取它).

解决方法

在考虑如何测试之前,我认为您可能会发现查看您要测试的内容很有价值.

从什么数据开始,我发现采用单个元素或少量数据确实很有帮助,并想象一下围绕它们的一组事件,以便为您提供正确的测试数据来运行您的测试.例如;

>如果您正在开发医疗保健系统,您可以定义一个人“Bob”,然后制作他的生活事件.鲍勃出生于37年前的今天,小时候从自行车上摔下来,摔断了手臂,结婚了,还有两个孩子.
>如果您正在开发金融交易系统,您可以查看一些股票的开盘和收盘之间的一天,例如: “MSFT”和“APPL”.在这一天你可能会看到一个从低位开始爬升,另一个从高位开始下降.一条新闻出现,扭转了他们的命运.

现在,您可以实际评估哪些方案实际上适用于您的数据,例如: “MSFT”和“APPL”全天可能会有1,000次价格变动,因此生成Givens和Mocks将非常耗时.该数据有助于预先捕获.另一方面,“Bob”数据在使用生成的数据时效果特别好,因为数据总是可以改变,所以今天是他的生日.

您的问题似乎不需要考虑的一件事是更新您的数据.例如,您可能希望在实体生命周期的不同阶段使用一组测试,例如:有些测试涉及“Baby Bob”,其他测试涉及“10yr old Bob”或“已婚Bob”等.如果您的数据库是只读的,那么如果您可以编写测试以便他们不这样做就不会有问题查看其他数据,但有时您希望通过测试构建故事.如果您的测试确实更改了数据,那么您将无法确保测试按顺序运行(请参阅MSTest OrderedTest或mbUnit DependsOn),或者您可以将测试分开,以便它们分别处理隔离的数据实体(这很好)如果您的实体可以在一行中描述,但是当您必须阅读许多表来获取它时会变得更难).

您也可能想要考虑您正在测试的代码,您可以改变不同测试集中的方法.我目前正在开发一个多层应用程序,它具有UI视图,视图模型,客户端模型,多个通信系统和服务器模型.我也有不同的测试集.我有一些测试工作在单层,模拟其他层,以保持我的测试小.其他测试启动本地服务器和本地客户端,并直接连接两者.最后,我有一些测试可以启动完整的服务器进程,通过EMS进行通信,并使用除UI视图之外的所有内容运行一些简单的客户端操作.

所以现在实际回答你的问题,

>影子复制你的数据库 – 是的,我已经用sqlServer Developer完成了一次,并且在运行测试之前有一个被复制的xxx.mdb.然而,一些现代测试框架将并行运行测试,例如,NCrunch,所以这只是休息.
>创建数据库并预先填充 – 未完成此操作,但我担心的是测试将数据库更改为意外状态时会发生什么.其他测试在没有做错的情况下会失败.
>创建数据库并使用Gi​​vens – 我已经通过Linq-to-sql DB上的[SetupFixture]使用NUnit完成了这项工作.你仍然担心并行测试运行,你必须平衡你的数量的粒度(见StackOverflow-When do BDD scenarios become too specific),您有数据更新排序/数据隔离问题,但这可以很好地帮助您处理数据故事并在整个测试过程中增加数据.另一方面,如果一个测试失败并使数据处于错误状态,您最终可能会遇到很多失败,但至少您只需要查看首先失败的那个.对于工作站上的开发人员来说,这种测试也不会很好,因为他们不能只运行一次测试,特别是使用NCrunch这样的工具,它可以运行代码已经改变的测试.>模拟数据库这就是我现在选择做的事情.诀窍在于,如果您亲自遵循一个相当严格的TDD流程,您只测试您正在使用的方法,那么您实际上最终会得到一些测试数据库交互的层,例如: [测试] DALLayerTests.ShouldReadARowAndCreatePOCO(),但大多数其他人使用模拟数据来测试实际发生的事情,例如[测试] BusinessObjectPersonTests.ShouldGetBirthdayCongratulations().>使用清理代码 – 从未尝试过,听起来很狡猾:-)

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 'EastRiver' 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...