我们有一个大型的测试套件,包含大约300多个测试。如今,我们正在手动恢复database并创建一些数据对象,并对一些数据进行硬编码以馈入测试。但是,很多测试需要更多数据,我们正在尝试通过测试生成它们。问题是当数据库更改或测试套件在具有不同版本数据库的另一台计算机上运行时,它们将失败。我的问题是


处理这种情况的最佳做法是什么?

必须有某种方法来处理数据库的已知状态。只是不知道它是什么。

我们使用C#NUnitSelenium WebDriver进行UI测试

#1 楼

由于UI测试变慢,我认为能够并行运行它们很重要。为了能够并行运行它们,您的数据管理将变得更加复杂,因为如果测试使用相同的数据源,它们可能会将数据更改为冲突状态并使测试随机失败,这就是为什么测试应该全部运行的原因隔离。

当前,我正在研究一个看起来像以下内容的新设置。

要求:


所有测试所需的最小数据集(从SQL脚本生成)
用于从代码生成用户和测试数据的函数,最好重用应用程序的实际内部类。 (以确保应用程序何时更改,数据的生成也会更改)。
描述和设置实际测试数据的Testsets类
Testsets生成到备份文件中,并且代码检查备份是否为基于指示数据库版本的增量编号仍然有效(开发人员针对每次数据库更改进行更新)。

每个测试运行都执行以下操作:


测试初始化​​


检查备份数据集是否仍然有效,并在需要时生成新数据
生成测试的唯一ID
使用以下命令将测试集恢复到数据库中名称中的唯一ID
配置应用程序/测试以使用正确的数据库


运行测试


安排(登录,准备额外的应用程序状态等)
采取行动(要测试的动作)
声明(验证动作是否成功)


测试清理


删除数据库
检查日志中的错误



恢复数据库所需的时间少于在我们的SSD上占用一秒钟的时间,在这里没有太多的开销。对于从头开始生成需要很长时间的数据集,我们将附加的数据集保存到单独的备份文件中,并在每次需要它的测试运行中将其还原。

由于每个测试都设置并使用自己的个人数据库,因此该测试可以在任何地方运行,并且始终有效。现在,构建服务器可以将测试推送到多个节点,并且每个测试都不会干扰其他测试。

运行测试的开发人员不需要在本地设置任何数据,因为测试将针对这些数据进行操作。他们。我们制作了一个单独的测试运行器,该测试运行器在本地设置了一个测试集,因此人们可以使用它对它进行手动测试以重现所发现的问题。

针对您特定情况的其他信息:



如何在nUnit中使用设置和拆卸

从C#恢复数据库


评论


嗨,老兄。感谢你的回答。如何完成从代码生成用户和测试数据的函数,最好重用应用程序的实际内部类。 (以确保应用程序更改时,数据的生成也会更改)使用Selenium或sql,您的建议是什么

–赛富尔
2015年2月23日下午13:58

您可以使用方法createUser(“ name”,“ password”,“ otherdetailsyouneedfortest”)创建一个用户类。该方法可以使用应用程序代码在系统中生成用户,类似于当用户使用维护屏幕创建用户或通过执行SQL查询时执行的代码。我不希望使用SQL查询,因为如果数据模型发生更改,则需要更新两个位置。原始代码和测试数据的生成。也许您可以要求本地应用程序开发人员帮助您设置类似的内容?

– Niels van Reijmersdal
2015年2月23日在19:19

#2 楼

这是一个非常有趣的问题。我认为我们不完全满意我们的方法,因此我们会定期讨论它,但这是我们的局限性以及迄今为止我们所做的事情(框架已经使用了大约3年)。

1)我们在每次测试开始时重新加载骨架数据库。它具有尽可能少的数据集-用户,最少的配置。一方面,我们有一个自动化套件,可以定期生成此数据库,以确保它保持同步。


我们不想为每个测试重新加载数据库,因为我们不想减慢测试的运行速度。
在启动框架时,底层数据库的变化非常迅速,而编写SQL脚本直接修改db将需要大量维护。

2)通用方法是测试通过API创建他们需要的数据(例如客户,订单等),以及是否进行重大更改(例如配置),那么他们需要在测试结束时撤消它们。能够使用API​​而不是UI来设置数据,可以在运行时更快地完成此操作。我们也知道数据将具有代表性,因为(大多数情况下)UI是如何创建数据的,因此我们不必担心测试数据会逐渐与实际实时数据分离。

我们现在面临的问题是,即使我们拥有的最小配置集也具有限制性-因此,我们需要考虑如何通过具有多个不同的骨架或能够在以下位置修改该配置来生成不同的配置运行时。

在具有不同版本数据库的另一台机器上运行测试非常容易-我们只需要设置自动化用户并更改一些配置设置(如果正在运行的测试子集需要这些设置) 。我们对实际的基础数据库设计几乎没有依赖性-您可以更改99%的表,并且只要应用程序代码仍然有效,我们仍然可以运行测试。举例来说,这意味着我们可以在集成测试未充分涵盖的区域中进行数据库更改时使用UI测试来检测问题。这可能对您来说不是问题。

评论


非常感谢您回答。您如何完成`我们在每次测试开始时重新加载骨架数据库?

–赛富尔
2015年2月23日下午13:55

在这种情况下,我们实际上不在测试框架内执行此操作-我们从CI服务器运行测试,并有一个步骤可以在其中重新加载db(就像“ mysql testaccount
– testerab
2015年2月23日在18:54



#3 楼

很难提供有关您特定过程的输入,但是这是我通常处理Selenium自动化的方式。


一个单独的数据库,其中包含测试的所有数据:数据驱动的测试。这意味着您可能必须组成视图(根据需要组合表),以用作测试方法的数据源。
将脚本插入/更新/删除作为存储过程到应用程序的数据库中。在运行任何测试之前,让您的测试类执行这些脚本。这样,您可以将应用程序中的“可变”数据强制为自动化测试所期望的特定状态。

示例说明:


对于测试方法“客户登录”,Selenium数据库提供customer@login.com和密码1234。因此,在使用此数据登录后,测试方法需要一个客户个人资料屏幕(否则将失败)。
在运行案例之前,将执行插入/更新/删除脚本。它将(1)删除应用程序数据库中现有的customer@login.com配置文件,然后(2)使用正确的密码和设置插入配置文件。这样我们就可以肯定我们的测试数据是正确的。如果我们不执行此脚本,则配置文件可能已通过手动测试进行了更改,密码可能已过时,...


评论


感谢您的宝贵答复。我现在就这样做。尽管这是我们的问题,但它是工资单应用程序以及复制用户行为所需的大量数据。如果我想编写我的插入/更新脚本,似乎比实际编写测试要多得多的工作,因为sql查询有时会很庞大。所以我想知道一个称为基线的数据库,并从那里获取它。

–赛富尔
15年2月21日在15:01

在这种情况下,@ saifur我建议您拍摄一个数据库快照,您可以在启动测试套件之前轻松地(手动)还原该快照。

– FDM
2015年2月21日在16:34