database - 具有数据库模式的SpecFlow集成测试

标签 database integration-testing specflow acceptance-testing

我正在尝试为集成/验收测试设置SpecFlow。我们的产品在Sqlite中有一个后备数据库(虽然不是一个很大的数据库)。

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

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

我可以想到以下方法:

  • 将数据库编译到带有测试的程序集中,然后对每个测试进行卷影复制。不过似乎很慢。
  • 我可以在内存中创建数据库,并用预定数据填充它。
  • 我可以在内存中创建数据库,并且Givens会以某种方式填充数据库。这似乎会使测试令人肿,但可能会赋予它们更多的控制权,并使测试的脆弱性降低。
  • 我可以抽象每个数据库交互并使用模拟。我不喜欢这个想法,因为我也想用它来测试数据库交互。
  • 将数据库编译到测试中,并依靠清理代码将其返回到基本状态(这对我来说似乎是狡猾的)。不想对事务执行此操作,因为与某些测试会有多次交互(因此先编写一个项目,然后尝试以不同的权限将其读回)。
  • 最佳答案

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

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

  • 如果您在医疗保健系统上工作,则可以定义一个人“鲍勃”,然后产生他的生活事件。鲍勃(Bob)出生于37年前的今天,小时候从自行车上摔下来摔断了胳膊,结婚了,育有两个 child 。
  • 如果您使用的是金融交易系统,则可能要看一下从开盘到收盘之间的几只股票之间的一天,例如“MSFT”和“APPL”。在这一天,您可能会看到一个从低点开始爬升,另一个从高点开始下跌。一则消息传来,扭转了他们的命运。

  • 现在您可以实际评估哪些方案对数据有效,例如“MSFT”和“APPL”全天可能会有1000的价格变化,因此生成Givens和Mocks会非常耗时。该数据适合于预先捕获。另一方面,“鲍勃”数据在使用生成的数据时效果特别好,因为数据总是可以更改的,所以今天是他的生日。

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

    您可能还需要考虑要测试的代码,因此可以在不同的测试集中使用不同的方法。我目前正在使用具有UI View , View 模型,客户端模型,多个通信系统和服务器模型的多层应用程序。对于这些我也有不同的测试集。我有一些可以在单个层中工作的测试,可以模拟其他层以保持我的测试小。其他测试将启动本地服务器和本地客户端,并将两者直接连接起来。最后,我进行了一些测试,这些测试可以启动完整的服务器进程,通过EMS进行通信并使用除UI View 之外的所有内容运行一些简单的客户端操作。

    所以现在要真正回答您的问题,
  • Shadow复制您的数据库-是的,我已经使用SQLServer Developer完成了一次,并复制了一个xxx.mdb,然后再运行测试。但是,某些现代测试框架将并行运行测试,例如NCrunch,所以这只是中断。
  • 创建数据库并预填充-未完成此操作,但我担心的是测试将数据库更改为意外状态时会发生什么。如果其他操作没有做错任何操作,则它们将失败。
  • 创建数据库并使用Gi​​vens-我已经通过Linq-to-sql数据库顶部的[SetupFixture]通过NUnit进行了此操作。您仍然担心并行测试运行,并且必须平衡给定的粒度(请参阅StackOverflow-When do BDD scenarios become too specific) ,并且您遇到了数据更新排序/数据隔离问题,但这确实可以很好地工作,以使您能够遍历数据故事并在整个测试过程中扩展数据。另一方面,如果一个测试失败并导致数据处于错误状态,则最终可能会导致很多失败,但是至少您只需要查看首先失败的测试即可。对于开发人员来说,这种测试也不太适合他们的工作站,因为他们不能只运行一个测试,尤其是使用NCrunch之类的工具,它可以运行代码已更改的测试。
  • 模拟数据库这就是我现在选择做的事情。诀窍是,如果您个人遵循一个相当严格的TDD流程,其中仅测试您正在使用的方法,那么实际上您最终会遇到一些测试数据库交互的层,例如[Test]DALLayerTests.ShouldReadARowAndCreatePOCO(),但其他大多数使用模拟数据来测试实际发生的情况,例如[Test]BusinessObjectPersonTests.ShouldGetBirthdayCongratulations()
  • 使用清理代码-从未尝试过,听起来很狡猾:-)
  • 关于database - 具有数据库模式的SpecFlow集成测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17047130/

    相关文章:

    javascript - Supertest:如何为发布到另一个 API 端点的 API 端点编写测试?

    c# - Specflow 2022 生成步骤定义文件 - VSC BDD : All steps have been defined in this file already

    database - 无模式数据库系统的吸引力是什么?

    mysql - 从两个名为共同 friend 和喜欢的表(关系)中找到一种喜欢的 friend 。SQL,数据库

    java - 如何使用 Spring MVC Controller 作为集成测试的假端点?

    azure-devops - 使用 SpecRun 在 VSTS 发布阶段执行 SpecFlow 测试

    database - 我应该如何实现这个 specflow 步骤?

    java - 数据库和服务器 UML

    mysql - 哪一个对(mysql)性能更好?

    asp.net - 单元/集成测试,它们应该有多细粒度?