我正在开发Web服务的验收测试。测试由Specflow驱动,并使用SQL Server CE作为数据库。该服务与其他应用程序和模块共享数据库,并使用通过其中一个应用程序创建的一些数据。
从我的产品的角度来看,有两种类型的“数据”:
在运行测试用例之前,您需要设置数据库的初始状态。对于仅消耗的数据,初始化数据的唯一方法是直接插入数据库。但是对于托管数据,我们可以直接在数据库中设置状态,也可以像用户那样设置状态,调用API。
例如,我想测试我的方法'updateItem'正确地将项目的价格更新为'y'。为了能够执行此方法,我需要使用价格为“x”的初始项设置我的数据库。有两种方法可以做到这一点:
第一种方法的优点是我只执行我想要测试的方法,所以如果测试失败,只会失败一个原因。缺点是,如果将来创建的项目的状态发生变化(添加新字段),我需要手动在初始状态下进行更改。
另一方面,第二种方法的利弊则相反。测试可能失败,因为'createItem'失败了,虽然一些测试框架会告诉你它是设置失败的,而不是实际的测试。但是,无论“createItem”发生什么变化,这些变化都会自动包含在您的测试中,您无需手动更新初始状态。
非常感谢任何建议。
答案 0 :(得分:1)
公平地说,你几乎已经解决了问题中的直接问题,你真的需要做出决定。
设置此数据的方法有很多种,比你提到的要多,虽然这个问题与SpecFlow Integration Testing with Database Patterns完全重复,但请先快速查看。
好的,现在选择,使用现有的API是否更好,或者不是?如果不是,那会怎么做?我猜你要写一些额外的SQL语句并直接调用它们。
这不是说你创建了另一个API吗?您已经获得了将价格设置为Y的外部API,以及将价格设置为X的新内部/测试API。因此,您必须将编写和维护的代码加倍。更糟糕的是,测试的快速和脏代码实际上最终会在整个测试过程中被复制和粘贴,所以当它打破时,你必须在很多地方修复它。
如果可以,请停止思考数据库。想想API。您提到您有一些静态数据只需要用于测试,因此将API组合在一起,如果它不公开,或者仅由您的应用程序使用,则无关紧要。获得该API。
接下来,替换API背后的内容。使用Mocks,使用内存中表示,NoSQL数据库,XML文件或任何您需要进行单独测试的通道,因为随着时间的推移,您将浪费太多时间来保持数据库正常工作。随着您的测试增加速度变得非常快,并且公平地说,您作为应用程序开发人员,不关心如果SQL CE是最佳解决方案。当系统架构师(即使你戴着不同的帽子)时,我们就会说我们需要采用这种技术并转向别的东西,至少你并不依赖它。
答案 1 :(得分:0)
Alski的答案很好,但我认为还有其他一些你应该考虑的问题。虽然调用应用程序的API来创建项目很好,但您应该警惕这种方法的长期影响,因为它可以使您的测试花费的时间比他们需要的时间长得多。如果你所做的只是调用CreateItem,那就没关系,但想象一下,随着你的应用程序的复杂性增加,如果你必须始终遵循用户工作流程,你可能最终只需要执行大量步骤来获得您想要的州的数据。如果您需要测试重新订购页面上可见的缺货商品,那么您可能需要执行以下所有操作:
只是为了确保您的产品存在且缺货。这可能需要很长时间(特别是如果你的测试是基于硒的)。
如果您刚刚将正确的数据插入到表中,那么运行速度会快得多。
这对你来说是否是一个问题,我不能说,但在做出决定之前要记住这一点。
幸运的是,specflow让你很容易改变主意。 Juts有一个类似
的步骤Given all the stock for <Product> has been sold
然后您可以通过调用其他步骤来执行用户工作流程或将数据直接推送到数据库中来实现它。