【问题标题】:How should automated acceptance tests use set up the initial state?自动化验收测试应该如何设置初始状态?
【发布时间】:2016-06-16 14:41:48
【问题描述】:

我正在开发 Web 服务的验收测试。测试通过 Specflow 驱动并使用 SQL Server CE 作为数据库。该服务与其他应用程序和模块共享数据库,并使用通过其中一个应用程序创建的一些数据。

从我的产品来看,“数据”有两种:

  1. 我们只使用的数据
  2. 我们创建/修改的数据

在运行测试用例之前,您需要设置数据库的初始状态。对于仅消费的数据,初始化数据的唯一方法是直接插入数据库。但是对于托管数据,我们可以直接在 DB 中设置状态,或者像用户一样调用 API。

例如,我想测试我的方法“updateItem”是否正确地将商品的价格更新为“y”。为了能够执行此方法,我需要使用价格为“x”的初始项目设置我的数据库。有两种方法可以做到这一点:

  1. 直接在数据库中设置item的状态
  2. 调用“createItem”

第一种方法的优点是我只执行我想测试的方法,所以如果测试失败,只有一个原因失败。缺点是,如果将来创建的项目的状态发生变化(添加新字段),我需要手动在初始状态下进行更改。

另一方面,使用第二种方法的利弊是相反的。测试可能会因为“createItem”失败而失败,尽管一些测试框架会告诉您失败的是设置,而不是实际测试。但无论“createItem”发生什么变化,这些变化都会自动包含在您的测试中,您不必手动更新初始状态。

非常感谢任何建议。

【问题讨论】:

    标签: entity-framework web-services automated-tests specflow acceptance-testing


    【解决方案1】:

    说句公道话,您已经在问题中确定了您的直接问题,您真的只需要做出决定。

    有很多方法可以设置这些数据,比你提到的要多,虽然这个问题与SpecFlow Integration Testing with Database Patterns 不太一样,但请先快速浏览一下。

    好的,现在选择,使用现有的 API 更好还是不使用更好?好吧,如果没有,该怎么办?我猜你会写一些额外的 SQL 语句并直接调用它们。

    这是否意味着您已经创建了另一个 API?您已经拥有将价格设置为 Y 的外部 API,以及将价格设置为 X 的新内部/测试 API。因此,您必须编写和维护的代码增加了一倍。更糟糕的是,用于测试的快速而肮脏的代码实际上最终会在整个测试过程中到处复制和粘贴,因此当它损坏时,您必须在很多地方进行修复。

    如果可以,请停止思考数据库。想想 API。您提到您有一些静态数据只需要用于测试,因此请组合一个 API 来执行此操作,它是否不公开或仅由您的应用程序使用都没有关系。准备好那个 API。

    接下来,替换 API 背后的内容。使用 Mocks,使用内存中的表示、NoSQL 数据库、XML 文件或任何您需要使单个测试通过的东西,因为随着时间的推移,您将浪费很多时间来保持该数据库的工作。随着您的测试增加,它会很快变慢,而且公平地说,作为应用程序开发人员,您不关心 SQL CE 是否是最佳解决方案。当系统架构师(即使那是你戴着不同的帽子)然后说我们需要采用这项技术并转向其他东西时,至少你不会被它束缚。

    【讨论】:

      【解决方案2】:

      Alski 的回答很好,但我认为您还应该考虑其他一些问题。虽然调用您的应用程序的 API 来创建您的项目很好,但您应该警惕这种方法的长期影响,因为它可能会使您的测试花费比他们需要的时间更长的时间。如果您所做的只是调用 CreateItem,那没关系,但是想象一下,随着您的应用程序变得越来越复杂,如果您必须始终遵循用户的工作流程,您最终可能不得不执行大量步骤才能获得数据处于您想要的状态。如果您需要测试缺货商品在重新订购页面上是否可见,那么您可能需要执行所有这些操作:

      • 创建用户
      • 创建产品
      • 设置ProductStockLevel
      • CreateOrderForAllStock
      • 发货单

      只是为了确保您的产品存在且缺货。这可能需要大量时间(特别是如果您的测试是基于硒的)。

      如果您首先将正确的数据插入到表中,这将运行得更快。

      这对你来说是否是个问题,我不能说,但在你做出决定之前请记住这一点。

      幸运的是,specflow 让您很容易改变主意。 Juts 有一个类似于

      的步骤
      Given all the stock for <Product> has been sold
      

      然后您可以通过调用其他步骤来执行用户工作流或将数据直接推送到数据库中来实现它。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-30
      • 2021-11-04
      • 2021-03-10
      • 2019-09-02
      • 1970-01-01
      • 2012-03-22
      • 2020-05-07
      • 2012-02-16
      相关资源
      最近更新 更多